module Main where
import System.Random as Random
maxSubSumSeq :: [Int] -> Maybe (Int, Int)
maxSubSumSeq xs | null xs = Nothing
| otherwise = let len = length xs in Just $ maxSubSumSeq' xs 1 (div (1+len) 2) len
maxSubSumSeq' :: [Int] -> Int -> Int -> Int -> (Int, Int)
maxSubSumSeq' xs i c j | i == j = (i, j)
| i == c = let leftValue = xs !! (i-1)
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
sums = [(leftValue,(i,c)), (leftValue+rightValue,(i,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
| otherwise = let leftSubSeqIndex = maxSubSumSeq' xs i (div (i+c) 2) c
leftMaxSubSumSeq = takeSubList (fst leftSubSeqIndex) (snd leftSubSeqIndex) xs
leftValue = sum leftMaxSubSumSeq
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
midValue = sum $ takeSubList (fst leftSubSeqIndex) (snd rightSubSeqIndex) xs
sums = [(leftValue,leftSubSeqIndex), (midValue,(fst leftSubSeqIndex,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
takeSubList :: Int -> Int -> [Int] -> [Int]
takeSubList = (\i j xs -> take (j-i+1) $ drop (i-1) xs)
makeOutPutStr :: Maybe (Int, Int) -> [Int] -> String -> String
makeOutPutStr value xs name = case value of
Nothing -> "invalid value"
Just index -> let subseq = takeSubList (fst index) (snd index) xs
in name ++ " maxsubseq index is: " ++ show index ++ " it's maxsumseq is: " ++ show subseq ++ " sum is: "++ show (sum $ subseq)
testValue1 = [-2,11,-4,13,-5,-2]
testValue2 = [-6,2,4,-7,5,3,2,-1,6,-9,10,-2]
main :: IO()
main = do
let testValue1Index = maxSubSumSeq testValue1
let testValue2Index = maxSubSumSeq testValue2
putStrLn $ makeOutPutStr testValue1Index testValue1 "testValue1"
putStrLn $ makeOutPutStr testValue2Index testValue2 "testValue2"
return ()
import System.Random as Random
maxSubSumSeq :: [Int] -> Maybe (Int, Int)
maxSubSumSeq xs | null xs = Nothing
| otherwise = let len = length xs in Just $ maxSubSumSeq' xs 1 (div (1+len) 2) len
maxSubSumSeq' :: [Int] -> Int -> Int -> Int -> (Int, Int)
maxSubSumSeq' xs i c j | i == j = (i, j)
| i == c = let leftValue = xs !! (i-1)
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
sums = [(leftValue,(i,c)), (leftValue+rightValue,(i,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
| otherwise = let leftSubSeqIndex = maxSubSumSeq' xs i (div (i+c) 2) c
leftMaxSubSumSeq = takeSubList (fst leftSubSeqIndex) (snd leftSubSeqIndex) xs
leftValue = sum leftMaxSubSumSeq
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
midValue = sum $ takeSubList (fst leftSubSeqIndex) (snd rightSubSeqIndex) xs
sums = [(leftValue,leftSubSeqIndex), (midValue,(fst leftSubSeqIndex,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
takeSubList :: Int -> Int -> [Int] -> [Int]
takeSubList = (\i j xs -> take (j-i+1) $ drop (i-1) xs)
makeOutPutStr :: Maybe (Int, Int) -> [Int] -> String -> String
makeOutPutStr value xs name = case value of
Nothing -> "invalid value"
Just index -> let subseq = takeSubList (fst index) (snd index) xs
in name ++ " maxsubseq index is: " ++ show index ++ " it's maxsumseq is: " ++ show subseq ++ " sum is: "++ show (sum $ subseq)
testValue1 = [-2,11,-4,13,-5,-2]
testValue2 = [-6,2,4,-7,5,3,2,-1,6,-9,10,-2]
main :: IO()
main = do
let testValue1Index = maxSubSumSeq testValue1
let testValue2Index = maxSubSumSeq testValue2
putStrLn $ makeOutPutStr testValue1Index testValue1 "testValue1"
putStrLn $ makeOutPutStr testValue2Index testValue2 "testValue2"
return ()
本文介绍了一种使用Haskell实现的最大子序列和算法,该算法能够找出整数序列中具有最大和的连续子序列及其起始和结束位置。通过递归方式实现了对不同长度子序列的求和比较,并给出了具体的实现代码及测试示例。
1071

被折叠的 条评论
为什么被折叠?



