Haskell子列表

时间:2012-05-21 16:55:57

标签: haskell

我必须创建一个找到特定子列表的函数。

function :: Integer -> Integer -> [[Integer]]
function n m = …
  • 如果m小于n程序退出。
  • 如果(mod (sum [1..n]) m) /= 0再次出错。
  • 否则程序应找到子列表。
  • 主要列表来自[1..n]

例如,如果数字为n = 6m = 7。列表为[1,2,3,4,5,6]答案为[[6,1],[5,2],[4,3]]

function 6 7
>>> [[6,1],[5,2],[4,3]]

没有必要订购。所以我已经做了这些步骤。任何帮助都会有用。此外,示例代码也很有用。如果有人能解决这个问题,我将不胜感激。使用解决方案的代码对我来说非常有用。

    function :: Integer -> Integer -> [[Integer]]
    function n m 
      |m < n = error "m is smaller than n"
      |(mod (sum [1..n]) m) /= 0 = error "list sum doesn't devide with m"
      |otherwise = …

2 个答案:

答案 0 :(得分:1)

我会用sum属性创建所有列表,例如使用list comprehension。然后按唯一性属性进行过滤,例如:

  1. 获取第一个子列表和生成器列表的列表差异,并检查生成器中是否包含下一个子列表,
    • 然后删除子列表(如果它不是更改的生成器的子集)
    • 或执行与1中相同的程序。
  2. 如果改变的发电机的总和小于m
  3. ,您可以结束程序

    请注意,结果取决于您对所有子列表进行排序的方式 - 因此解决方案不是唯一最长的子列表列表,而只是使用sum和“uniqueness”属性的许多结果中的一个。


    编辑:某些代码 - 不完美的最大解决方案

    只是要开始并考虑我只收集简单的两个元素列表,否则采取一个最大列表。

    接下来的改进是使一个函数不仅收集简单而且收集所有两个元素列表,然后将其概括为获得给定长度的子列表,也许你想看一下基本组合。

    module Sublists where
    import Data.List ((\\))
    
    subLists :: Int -> Int -> [[Int]]
    subLists n = subLists' ([],[1..n])
    
    subLists' :: ([[Int]],[Int]) -> Int -> [[Int]]
    subLists' aa m = fst (mLSubLists (tLSubLists aa m) m)
    
    _subLists :: ([Int] -> Int -> [Int]) -> ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
    _subLists _ yx@(_,[ ]) _ = yx
    _subLists _ yx@(_,[_]) _ = yx
    _subLists f yx@(yy,xx)  m | sum xx < m = yx
                           | otherwise  = if tt == []
                                            then yx
                                            else _subLists f (tt:yy,xx\\tt) m
                           where tt = f xx m
    
    tLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
    tLSubLists = _subLists twoList
    
    mLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
    mLSubLists = _subLists manyList
    
    
    twoList :: [Int] -> Int -> [Int]
    twoList [ ]    _ = []
    twoList [_]    _ = []
    twoList xx@(x:xs) m | (x + l) < m         = []
                        |  x == l              = []
                        | (x + l) `rem` m == 0 = [x,l]
                        | otherwise           = twoList ii m
                        where l  = last xs
                              ii = init xx
    
    manyList :: [Int] -> Int -> [Int]
    manyList xx m | s < m         = []
                  | s == m         = xx
                  | s `rem` m == 0 = xx
                  | otherwise     = manyList xs m
                  where s  = sum xx
                        xs = tail xx
    

    和一些测试用例:

    import Sublists
    import Test.HUnit
    import Data.List ((\\))
    
    main = testAll
    
    testAll = runTestTT $ TestList tests
    
    tests :: [Test]
    tests = [
       "n=6 m=7" ~: "subLists"  ~:  [[3,4],[2,5],[1,6]]
                                ~=? subLists 6 7,
       "n=6 m=7" ~: "twoList"   ~:  [1,6]
                                ~=? twoList [1..6] 7,
       "n=6 m=7" ~: "twoList"   ~:  [2,5]
                                ~=? twoList ([1..6]\\[1,6]) 7,
       "n=6 m=7" ~: "twoList"   ~:  [3,4]
                                ~=? twoList (([1..6]\\[1,6])\\[2,5]) 7,
       "n=6 m=7" ~: "manyList"  ~:  [2,3,4,5]
                                ~=? manyList [1..5] 7,
       "dummy"   ~: "dummy"     ~:  "result"
                                ~=? (\_ -> "result") "function"
                                ]
    

答案 1 :(得分:0)

subsequences中的Data.List功能可能会有所帮助,例如

subsequences "abc" == ["","a","b","ab","c","ac","bc","abc"]

然后你“只是”需要过滤掉与你的标准不符的所有子列表。