如何停止递归并在内存中生成列表

时间:2014-10-23 15:12:10

标签: haskell recursion

(1。)函数" sameString"返回一个布尔值,表示两个字符串是否相同而不管大小写。

--  *Main> sameString "HeLLo" "HElLo"
--   True
--   *Main> sameString "Hello" "Hi there"
--   False


sameString :: String -> String -> Bool
sameString str1 str2
    | length str1 == length str2 = and [ a == b | (a,b) <- zip (capitalise str1) (capitalise str2) ]
    | otherwise = False

(1)助手功能&#34;大写&#34;资本化。

capitalise :: String -> String
capitalise str = [ toUpper x | x <- str ]

(2)功能&#34;前缀&#34;返回一个布尔值,该值指出第一个字符串是否是第二个字符串的前缀,而不管大小写。

--  *Main> prefix "bc" "abCDE"
--  False
--  *Main> prefix "Bc" "bCDE"
--  True

prefix :: String -> String -> Bool
prefix [] [] = True
prefix substr str
    | sameString string' substr == True = True
    | otherwise = False
    where chop_str :: String -> String -> String
          chop_str str substr = (take (length substr) str)
          string' = chop_str str substr   

(3。)功能&#34; dropUntil&#34;在第一次出现第一个字符串后返回第二个字符串的内容。如果第二个字符串不包含第一个字符串作为子字符串,则应返回空字符串。

*Main> dropUntil "cd" "abcdef"
"ef"

 dropUntil :: String -> String -> String
 dropUntil substr [] = ""
 dropUntil substr (s:tr)
    | prefix substr (s:tr) == False = drop 1 s : dropUntil substr tr
    | prefix substr (s:tr) == True =  

所以现在问题。我正在考虑用递归做dropUntil。

我认为上述功能应该是:

1)给定字符串和子字符串(子字符串不是字符串的前缀)...

它应该掉落字符串的头部......

并清空空列表&#34;&#34;到

...对剩余尾部和相同子字符串的递归调用。

它背后的想法是不断删除列表的头部,直到子字符串成为列表的前缀,然后函数应该生成字符串的剩余部分。

但是,我不知道该怎么做。我基本上想做的是make

| prefix substr (s:tr) == True =  "leftover_string"

&#34; leftover_string&#34;在递归调用删除元素之后剩余的内容,直到满足条件,即子字符串是余数的前缀。

这可以按我开始的方式进行吗?

2 个答案:

答案 0 :(得分:2)

在过去的几天里,我们遇到了很多问题,其中涉及与其他[x] [x]等待isPrefixOf的{​​{1}}。从那时起,我思想过程中出现的一个原语在这里非常有价值:

import Data.List

splitAtSublist :: ([x] -> Bool) -> [x] -> Maybe ([x], [x])
splitAtSublist pred list = find (pred . snd) $ zip (inits list) (tails list)

字符串zip (inits list) (tails list)的拆分"abcd"看起来像[("", "abcd"), ("a", "bcd"), ("ab", "cd"), ("abc", "d"), ("abcd", ""))]。这找到了&#34;尾部&#34;的第一个元素。分裂符合谓词pred

要从此基础获得dropUntil s,我们可以这样做:

dropUntil p ls = 
    maybe "" (drop (length p) . snd) $ 
        splitAtSublist (p `isPrefixOf`) ls

其中isPrefixOf也来自Data.List。代替,我们发现我们根本不使用inits list而只是变成:

dropUntil p = maybe "" (drop $ length p) . find (p `isPrefixOf`) . tails

这很简单,我可以得到它。

答案 1 :(得分:0)

这是你想要的吗?

| prefix substr (s:tr) == True =  drop (length substr) (s:tr)

一些注意事项:

这里有类型错误:

| prefix substr (s:tr) == False = drop 1 s : dropUntil substr tr
                                  ^^^^^^^^

我想你只是想:

| prefix substr (s:tr) == False = dropUntil substr tr