如何在Haskell中创建一个起始/结束索引列表?

5
我正在尝试编写一个Haskell函数,该函数以两个字符串作为参数。第一个字符串是我们想要在第二个参数中定位的字符串,并返回一个元组列表,其中包含每个出现位置的起始和结束索引。例如,
indexTuples :: String -> String -> [(Int, Int)]
indexTuples "aa" "foobaarfoobaar" 

Output: [(4,5), (11,12)] 

到目前为止,我已经编写了一个辅助函数来查找索引(我试图仅使用预定义方法而不是额外的方法来实现)。

我的辅助函数接受一个字符串和一个字符,并返回索引,就像这样:

findPos :: (Num a1, Enum a1, Eq a2) => [a2] -> a2 -> [a1]
findPos str c = [index | (x, index) <- zip str [0..], x == c]

我在这里找到了这个解决方案(链接)。这个函数将字符串与无限数字列表压缩成元组,然后选择其中字符等于参数c的元组,并返回每个元组的索引。这给了我这个输出:

Ok, one module loaded.
ghci> findPos "blablabla" 'b'
[0,3,6]

那么如何使它接受两个字符串呢? 像这样:

ghci> findPos "blablabla" "bl" 
[(0,1), (3,4), (6,7)] 

我尝试将变量c从字符类型更改为字符串类型,但是在ghci中出现了多个错误。


3
这看起来与这个最近的Haskell问题非常相似。 - jpmarinier
1
如果您允许自己重用Data.List中的现有函数,那么您可以编写findPos haystack needle = findIndices (needle `isPrefixOf`) (tails haystack) - Daniel Wagner
我不能使用Prelude以外的其他函数。但是我可以自己编写函数,所以我一直在尝试制作一个findIndices,按照这个问题中展示的相同方法 https://stackoverflow.com/questions/67012288/i-am-wanting-to-create-my-own-version-of-findindices-in-haskell,但我无法使其在两个字符串上工作,而不是在一个字符串和一个字符串列表上。 - Mampenda
1个回答

1
一个(非空)字符串有一个头元素,一个 Char:
indexTuples :: String -> String -> [(Int, Int)]
indexTuples []     _   = []
indexTuples (c:cs) str =

在另一个字符串中找到它的索引,-- 对于所有出现的情况,-- 使用您已经拥有的函数findPos返回它们的列表

  let
    ixs = findPos str c

我们尝试其中的每一个。
    len = length cs
    fits = [ (i,i+len) | i <- ixs, cs == (take len $ drop i str)]

这就是我们的答案。

   in
      fits

当我尝试在VS Code中编写这段代码时,出现错误:“´cs == (drop 1 $ take len $ drop i str)´”,错误提示为:无法匹配期望类型‘Char’和实际类型‘[Char]’ 在‘(==)’的第二个参数中, ‘(drop 1 $ take len $ drop i str)’ 是表达式:c == (drop 1 $ take len $ drop i str) 是列表推导式的语句: c == (drop 1 $ take len $ drop i str)typecheck(-Wdeferred-type-errors)当我试图通过移动括号来避免使用‘$’来修复它时,我又得到了另一个错误。如何在没有错误的情况下重写这一行代码? - Mampenda
我现在不认为会出现这种情况,也许你打错了字?但我会测试一下。 - Will Ness
我也感到困惑,因为我逐字地重写了它。 - Mampenda
2
你不应该写而是复制粘贴。我在GHCi中尝试了我的代码,没有错误。drop 1 是错误的,它不应该存在。但这被视为一种差一错误。 :) - Will Ness
1
从错误来看,您在转录代码时写成 c == ... 而不是 cs == ...。糟糕! - Daniel Wagner
是的,我做到了!谢谢。 - Mampenda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接