好的,所以一直遇到一个问题,基本上我被告知制作多重集或元组列表。 (Char,Int)然后我必须编写一个函数,它接受一个项并将其插入到这个列表中,但是如果列表中已经有匹配的元组,它会增加Int。 即我有一个清单[(p,2),(w,3)]我得到另一个它应该给[(p,2),(w,4)] 你会怎么做,我已经尝试了
listAdd :: Char->Int->ListOfT -> ListOfT
listAdd c i l
|length l == 0 =(c,i):l
|fst l == c = (c,i+1):l
但这会产生大量错误,我需要删除该点的list元素并将其替换为(c,i + 1),那么我如何从列表中删除以及如何获得i + 1?另外你如何制作一个循环,它将遍历列表中的所有元素? 我无法使用任何导入数据 我知道这要求很多,但任何帮助都会非常感谢。 新
好的,这段代码可以摆弄,所以它可以用来制作任何项目的元组而不仅仅是字符。所以我可以加载它并制作一个带有stirngs的元组列表,然后关闭它然后重新加载它并创建一个int元组列表?
答案 0 :(得分:3)
好吧我觉得你的想法不错,你只需要直接了解细节。
你询问的循环通常是通过递归完成的(因为列表是一个很好的想法的递归结构),或者是一些更高阶函数,如map
, filter
,foldr
,...这将隐藏你的递归(你可以说它们抽象出重复的东西) - 在这种情况下,我认为最简单的方法就是和你一起去开始并使用直接递归。
这是一个简单的版本(你可能想要扩展),它可以完成基本的工作:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c ((c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = (c',i) : listAdd c xs
你可以看到第一种情况与你所拥有的非常类似:如果字典(第二个参数)是空列表,那么你只需添加一个新的元组,并插入字符和数字1
如果没有那么你检查字典中的第一个元素是否具有相同的字符(这里是c'
),如果是,那么你增加计数,如果不是,你让这个元素保持不变并递归搜索字典的其余部分。
另请注意,您可以在此处使用模式匹配,不仅可以将字典解构为head::tail
形式,还可以将头部解构为(..,..)
元组部分。
如果您愿意,可以在那里使用@
并使第二种情况更简洁:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c (x@(c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = x : listAdd c xs
PS:如果你想知道为什么我没有使用你的Int
参数?因为如果已经存在价值,我不知道你想用它做什么 - 这是一个版本,我只是将它添加到它(似乎合理):
listAdd :: Char -> Int -> [(Char,Int)] -> [(Char,Int)]
listAdd c i [] = [(c,i)]
listAdd c i (x@(c',i'):xs)
| c' == c = (c,i+i'):xs
| otherwise = x : listAdd c i xs
答案 1 :(得分:2)
使用递归函数进行列表操作对于初学者来说确实很难理解,但在这种情况下,它们应该很好地适应问题。
让我们从更好的签名和帮助开始。
type MyList = [(Char, Int)]
listAdd :: Char -> MyList -> MyList
listAdd p l = listAdd' p [] l
请注意,我已将签名更改为仅接受Char
;我们不需要提供初始计数,因为如果列表中当前没有这样的元素,我们只需在添加新元素时将其设置为1.
好的,那是基本的骨架。帮助器只是为了更容易存储已经处理过的"列表的一部分。让我们看一下:
listAdd' :: Char -> MyList -> MyList -> MyList
首先,我们添加递归结束条件:
listAdd' p left [] = left ++ [(p, 1)]
这意味着如果我们之前没有找到要替换的元素,我们可以在最后添加它。
listAdd' p left (x:right) = if p == fst x
then left ++ [(fst x, snd x + 1)] ++ right
else listAdd' p (left ++ [x]) right
好的,现在我们分开了'#34;对"部分到它的第一个元素和其余部分。我们来看看if
:
作为最后的补充说明,您可以轻松地将Char
更改为Eq a => a
,以允许您的函数处理可以直接比较的任何类型,包括Char
。