【问题标题】:Haskell: brute force and maximum subarray problemHaskell:蛮力和最大子数组问题
【发布时间】:2012-09-14 11:42:01
【问题描述】:

我正在尝试用蛮力方法解决maximum sub array problem,即生成所有可能的子数组组合。我得到了一些有用的东西,但它根本不令人满意,因为它产生了太多重复的子数组。

有谁知道用最少数量的重复元素生成所有子数组(以 [[]] 形式)的聪明方法吗?

顺便说一句,我是 Haskell 的新手。这是我目前的解决方案:

import qualified Data.List as L

maximumSubList::[Integer]->[Integer]
maximumSubList x = head $ L.sortBy (\a b -> compare (sum b) (sum a)) $ L.nub $ slice x
     where 
        -- slice will return all the "sub lists"
        slice [] = []
        slice x = (slice $ tail x) ++ (sliceLeft x) ++ (sliceRight x)

        -- Create sub lists by removing "left" part
        -- ex [1,2,3] -> [[1,2,3],[2,3],[3]]
        sliceRight [] = []
        sliceRight x = x : (sliceRight $ tail x)

        -- Create sub lists by removing "right" part
        -- ex [1,2,3] -> [[1,2,3],[1,2],[1]]
        sliceLeft [] = []
        sliceLeft x = x : (sliceLeft $ init x)

【问题讨论】:

  • 请注意,您使用的是链表,而不是数组,因此您的算法不会像您期望的那样复杂。
  • @DonStewart 你说得对,我正在使用列表。实际上,由于问题的名称(“最大子数组”),我在描述中提到了“数组”,我猜这是个坏主意
  • 我不得不咯咯地笑“我正在使用蛮力方法......但它一点也不令人满意......”。

标签: algorithm haskell


【解决方案1】:

标准Data.List 模块中有许多有用的函数可用于对列表进行操作。

import Data.List

slice :: [a] -> [[a]]
slice = filter (not . null) . concatMap tails . inits

【讨论】:

  • concatMap tails.inits 这是完美的,这正是我想要制作的(我的大脑还没有准备好......)。谢谢
【解决方案2】:

dave4420's answer 是如何使用智能、简洁的 Haskell 来做你想做的事。我不是 Haskell 专家,但我偶尔会玩弄它,发现解决这样的问题是一种有趣的分心,并喜欢弄清楚它为什么有效。希望下面的解释会有所帮助:)

dave4420 的答案(您的答案没有)的关键属性是 (startPos, endPos) 对对于它生成的每个子数组都是唯一的。现在,如果startPosendPos 不同,则观察两个子数组是不同的。将inits 应用于原始数组会返回一个子数组列表,每个子数组都具有唯一的startPos 和相同的endPos(等于数组中元素的数量)。依次将tails 应用于这些子数组中的每一个,会生成另一个子数组列表——每个输入子数组都会输出一个子数组列表。请注意,tails 不会干扰输入子数组之间的区别,因为通过在单个输入子数组上调用 tails 输出的子数组都保留相同的 startPos:也就是说,如果您有两个子数组具有不同的startPoses,并将它们都放入tails,从第一个输入子数组生成的每个子数组都将不同于从第二个输入子数组生成的每个子数组。

此外,在单个子数组上调用tails 生成的每个子数组都是不同的,因为尽管它们都共享相同的startPos,但它们都有不同的endPoses。因此(concatMap tails) . inits 产生的所有子数组都是不同的。只需要注意没有遗漏任何子数组:对于从位置i 开始并在位置j 结束的任何子数组,该子数组必须显示为通过将tails 应用于@987654342 生成的j-i+1th 列表@th 列表由inits 生成。所以总而言之,每个可能的子数组只出现一次!

【讨论】:

    猜你喜欢
    • 2017-06-13
    • 2017-02-15
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2021-05-28
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多