Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 从无限列表中获取长度为4的所有子字符串_List_Haskell_Functional Programming_Infinite_Enumerate - Fatal编程技术网

List 从无限列表中获取长度为4的所有子字符串

List 从无限列表中获取长度为4的所有子字符串,list,haskell,functional-programming,infinite,enumerate,List,Haskell,Functional Programming,Infinite,Enumerate,我是Haskell的新手,我正在尝试解决以下问题: 我有一个函数,它生成一个无限长的字符串列表。但是一定长度的字符串的数量是有限的 现在我想提取列表中具有一定长度n的所有子字符串。不幸的是,我做了很多研究,尝试了很多东西,但都不管用 我知道filter()无法工作,因为它会检查列表的每个部分,并导致无限循环 这是我生成无限列表的函数: allStrings = [ c : s | s <- "" : allStrings, c <- ['R', 'T', 'P']] allStr

我是Haskell的新手,我正在尝试解决以下问题:

我有一个函数,它生成一个无限长的字符串列表。但是一定长度的字符串的数量是有限的

现在我想提取列表中具有一定长度n的所有子字符串。不幸的是,我做了很多研究,尝试了很多东西,但都不管用

我知道
filter()
无法工作,因为它会检查列表的每个部分,并导致无限循环

这是我生成无限列表的函数:

allStrings =  [ c : s | s <- "" : allStrings, c <- ['R', 'T', 'P']]

allStrings=[c:s | s问题在于,您的筛选器无法生成任何解决方案。为了生成长度为
4
的字符串,您首先需要生成长度为
3
的字符串,因为您每次都在该字符串前加一个字符。为了生成长度为
3
的列表,因此需要生成长度为
2
的字符串,依此类推,直到基本大小写:空字符串

主要的问题不是过滤器本身,问题是过滤器的过滤方式现在不可能发出值

我们可以通过使用不同的列表来修复此问题,该列表将生成字符串,并对该列表进行如下筛选:

allStrings = filter ((==) 4 . length) vals
    where vals = [x | x <- [ c : s | s <- "" : vals, c <- "RTP"]]
请注意,在这里,当我们生成下一个字符串时,最后一个字符首先会发生变化。我将其作为一个练习,以获得相反的结果。

allStrings4 = takeWhile ((== 4) . length) . 
                dropWhile ((< 4) . length) $ allStrings
allStrings4=takeWhile((==4).length)。
dropWhile(<4.length)$allStrings
这就是诀窍

它之所以有效,是因为您的(第一个)
allStrings
定义巧妙地生成了所有包含
'R'
'T'
、和
'p'
字母的字符串,它们以非递减的长度顺序以高效的方式出现

不要试图把所有的问题都塞进一个定义中,而是把你的关注点分开!首先为更一般的问题建立一个解决方案(这是你的
allStrings
定义),然后用它来解决更受限制的问题。这通常会简单得多,特别是对于Haskell的惰性计算


我们只需要注意,我们的流始终是高效的,从不停滞。

过滤器
不会导致无限循环,因为它以一种惰性的方式工作。只有当您完全评估列表时,它当然会停滞在无限循环中。allStrings=[c:s|s@WillemVanOnsem不会
print.filter(>0)$[0..]
“完全评估列表”?@T.Naz:那是因为你的
allString
永远不会发出什么东西,因为你说它应该是长度
4
,但是为了在这里构建长度
4
的列表,你首先需要
allString
s来构建长度
3
的列表,等等。@WillNess:是的,正如前面所说的,
print
会完全评估列表,因此一旦您开始打印,可以说,您将永远无法摆脱它。
allStrings
这里指的是您的第一个定义。永远不要使用相同的名称来表示不同的内容。始终对它们进行编号:
allStrings
allStrings2
,等等,这样就不会产生混淆。“不要用同一个名字来指代不同的事物"有点难理解。在整个程序过程中,我们通常使用
xs
来引用许多不同的内容。我不知道您的确切意思,因此我不能建议您进行很好的澄清。我认为更好的指导原则是避免名称阴影,除非您非常确定要这样做。编译器如果您启用
-Wall
-Wname shadowing
@amalloy,我最终的意思是“在同一个问题中”。或者更广泛地说,在GHCi提示下的探索“交互式播放”期间,将警告您这一点。(顺便说一句,我很惊讶这是不清楚的。很明显,这句话是在上下文中说的,我想,OP询问了两个同名的不同定义,这令人困惑,等等——所有这些都在同一条评论中提到)
Prelude Control.Monad> replicateM 4 "RTP"
["RRRR","RRRT","RRRP","RRTR","RRTT","RRTP","RRPR","RRPT","RRPP","RTRR","RTRT","RTRP","RTTR","RTTT","RTTP","RTPR","RTPT","RTPP","RPRR","RPRT","RPRP","RPTR","RPTT","RPTP","RPPR","RPPT","RPPP","TRRR","TRRT","TRRP","TRTR","TRTT","TRTP","TRPR","TRPT","TRPP","TTRR","TTRT","TTRP","TTTR","TTTT","TTTP","TTPR","TTPT","TTPP","TPRR","TPRT","TPRP","TPTR","TPTT","TPTP","TPPR","TPPT","TPPP","PRRR","PRRT","PRRP","PRTR","PRTT","PRTP","PRPR","PRPT","PRPP","PTRR","PTRT","PTRP","PTTR","PTTT","PTTP","PTPR","PTPT","PTPP","PPRR","PPRT","PPRP","PPTR","PPTT","PPTP","PPPR","PPPT","PPPP"]
allStrings4 = takeWhile ((== 4) . length) . 
                dropWhile ((< 4) . length) $ allStrings