用字符串替换Ints

时间:2015-01-13 16:42:00

标签: haskell

我需要练习帮助。我正在尝试编写一个名为“refer”的函数,该函数将使用引用([n])获取小说和任何给定文本的列表,并将返回该文本,并将引号替换为小说的名称。

参考将具有以下签名:

refer :: [(String, String, Int)] -> String -> String

例如,这就是它的运行方式:

> refer [("author1", "novel1", 1999),("author2", "novel2", 2000)] txt
> "novel1(author1, 1999) and novel2(author2, 2000) are my favorite books of all time, but I like novel2(author2, 2000) the most!"

我写了一个名为txt的函数,它将显示我将使用的文本。

txt :: String
txt = "[1] and [2] are my favorite books of all time, but I like [2] the most!"

我写了一个名为format的辅助函数,它将帮助我将小说格式从(“author1”,“novel1”,1999)格式化为“novel1(author1,1999)”

format :: (String, String, Int) -> String
format (name, novel, yearInt) = novel  ++ " (" ++ name ++
                            ", " ++ (show yearInt) ++ ")" 

我认为我需要做什么:

步骤1:我需要使用单词将输入分解为字符串列表 第2步:我应该创建一个辅助函数来解析列表,如果我找到引文,我应该使用格式替换该引文并递归解析列表的其余部分,直到我检查了所有内容。
第3步:创建一个辅助函数,将引用数字的字符串表示转换为Int(可能是unwords),因为我必须将引文替换为给定列表中的相应元素。 /> 第4步:然后我需要使用rewords将我更新的列表转换回字符串。

我有多远:

refer :: [(String, String, Int)] -> String -> String
refer [] "" = ""
refer books txt = [string'| y <- words txt, ........... ]
-- I'm trying to say that I want to take the inputted list of
-- novels and text and turn them all into strings and store
-- them into y which will be represented by string'. I am not
-- sure what to do after this.

2 个答案:

答案 0 :(得分:1)

您可以使用words,但之后会丢失有关单词之间空白区域的信息 - 即words "a b"等于words "a b"。也许这并不重要,但要记住这一点。

如果没有提供确切的解决方案,这里有一个函数用 a&#39; b 替换 a b&# 39; 在列表中:

replace a a' b b' [] = []       -- base case
replace a a' b b' (x:xs) =  c : replace a a' b b' xs
   where c = if x == a then a' else if x == b then b' else x

也许你可以弄清楚如何使这适应你的问题。

另请注意,此功能可以使用map

编写
replace a a' b b' xs = map f xs
  where f x = if x == a then a' else if x == b then b' else x

这种字符串处理的另一种方法是对字符进行模式匹配。这是一个删除所有&#34; cat&#34;来自一个字符串:

removeCat :: String -> String
removeCat ('c':'a':'t':rest)   = rest   -- "cat" found so remove it
removeCat (x:rest)             = x : removeCat rest

答案 1 :(得分:0)

如果是家庭作业问题,请不要逐字复制。

解决一般问题更容易。

首先,您需要replace函数来替换子字符串。一个简单的实现可以是

replace :: String -> String -> String -> String
replace old new [] = []
replace old new input = if (take n input == old) then new++(recurse n)
                    else (take 1 input)++(recurse 1)
                    where n = length old
                          recurse k = replace old new $ drop k input 

尝试匹配&#34; old&#34;从输入开始,如果匹配则替换并跳过旧的长度,如果不匹配则移动一个位置并重复。

到目前为止,这将取代所有出现的&#34; old&#34;到&#34;新&#34;。但是,您需要多个不同的替换。为此,让我们写另一个功能。为了最大限度地减少验证,我们假设我们将所有替换配对。

replaceAll :: [(String,String)] -> String -> String
replaceAll [] input = input
replaceAll ((old,new):xs) input = replaceAll xs $ replace old new input

您可以通过定义

等类型来更好地制作顶级签名
type Novel = (String,String,Int)

最后,

refer :: [Novel] -> String -> String
refer [] text = text
refer ns text = replaceAll p text
                   where p = [ ("["++show i++"]",format n) | (i,n) <- zip [1..] ns]

注意引文输入来自小说的位置。