我在Haskell中编写了这个使用列表理解的函数。
search :: String -> Char -> [Int]
search str letter = [ num | (x, num) <- (zip str [0..]), letter == x]
如何使用递归定义同一个函数,而不使用像zip
这样的库函数?我被允许使用辅助功能。
答案 0 :(得分:2)
这是一些建议。
在这种递归方案之后,可以找到一种非常有效但有效的解决方案。
search :: String -> Char -> [Int]
search [] letter = ???
search (x:xs) letter = doSomethingWith (search xs letter)
where doSomethingWith :: [Int] -> [Int]
doSomethingWith ns = ???
考虑如何将递归调用的结果转换为实际结果。例如:
search "abcb" 'b' = doSomethingWith (search "bcb" 'b')
= doSomethingWith [0,2]
should be
[1,3]
search "bbcb" 'b' = doSomethingWith (search "bcb" 'b')
= doSomethingWith [0,2]
should be
[0,1,3]
请注意,在doSomethingWith
中,您可以参考x
并检查它是否等于letter
。
为了获得更好的解决方案,请尝试添加一个额外的参数,以便传递当前位置的索引。例如:
search :: String -> Char -> [Int]
search str letter = searchWorker str letter 0 -- initial position is 0
searchWorker :: String -> Char -> Int -> [Int]
searchWorker [] letter position = ???
searchWorker (x:xs) letter position =
-- increment position at every recursive call
doSomethingWith (searchWorker xs letter (position+1))
where doSomethingWith :: [Int] -> [Int]
doSomethingWith ns = ???
这简化了doSomethingWith
的编码,因为现在可以假设递归调用产生正确的索引。
searchWorker "abcb" 'b' 0
= doSomethingWith (searchWorker "bcb" 'b' 1)
= doSomethingWith [1,3]
should be
[1,3]
searchWorker "bbcb" 'b' 0
= doSomethingWith (searchWorker "bcb" 'b' 1)
= doSomethingWith [1,3]
should be
[0,1,3]
答案 1 :(得分:2)
你有
search :: String -> Char -> [Int]
search str letter = [ num | (x, num) <- (zip str [0..]), letter == x]
它的作用是沿着输入的字符列表(字符串),同时为每个新字符增加索引值1。在执行此操作时,它会测试该字符是否与指定的相同,如果是,则生成它(或者更确切地说是它的索引)。
因此,我们最好通过保护递归对此进行建模,这使我们能够在找到它们时立即生成每个找到的字符(或其索引)。
search str letter = go str <initial-index-value>
where
这里我们是我们领域的主人,我们可以为我们想要的内部函数提供许多参数 - 我们不限于由列表推导的<-
运算符指示的压缩对。此外,我们可以自己计算,根据需要创建新的指数。
go [] _ = -- we've reached the end of the input.
-- we should finish up our output
.... -- ok, it's the end of any list - an empty list
go (x:xs) i
| x == letter =
我们可以访问letter
,因为go
是我们search
的内部函数,因此我们可以对它们进行比较。在这里,我们想立即生成这个索引
i : <a recursive call with updated parameters>
| otherwise =
这里没什么可生的,只需要制作
<a recursive call to continue the search
on input list's tail, with the new
current index value>
我们已经完成了。