求最大子序列和 - Haskell

来源:互联网 发布:太阳能系统计算软件 编辑:程序博客网 时间:2024/06/06 07:37
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 ()
0 0
原创粉丝点击