我在Haskell中创建了一个[Integer]
的序列。序列的数学定义使得它对于一些正整数重复。在这种情况下,我想终止序列并确定有限列表的长度。
我尝试解决方案是首先从数学序列创建一个无限列表。然后我想过滤所有元素的列表,直到第一个元素重复。结果不应包括列表的重复头部。
我有两个问题/疑虑:
1)如何将列表的头部与列表后面的元素相匹配? 2)这是解决我问题的有效方法吗? (如果需要,我将在稍后添加有关确切序列的更多详细信息。现在我正在寻找一般性评论。)
答案 0 :(得分:10)
您描述的算法可以简单地实现如下:
findPeriodic :: Eq a => [a] -> [a]
findPeriodic [] = error "there are no periodic sequences in the empty list"
findPeriodic (x : xs) = x : takeWhile (/= x) xs
它完全符合您的描述:它占据了一些列表的头部,并收集列表的一部分,直到该头元素再次出现在列表中。所以,例如:
list = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, ...]
findPeriodic list => [1, 2, 3, 4, 5]
答案 1 :(得分:2)
第一个元素可能永远不会在1,2,3,4,5,3,4,5,3,4, ...
这样的序列中重复,其中(a !! i) == (a !! j) ==> (a !! (i+1)) == (a !! (j+1))
(就像您在评论中添加的那样,这与您在问题中的要求不同)。
这被称为cycle detection,最近讨论过,例如here。