繁体   English   中英

Haskell和操作元组列表

[英]Haskell and manipulating a list of tuples

好的,所以遇到了一个问题,基本上我被告知要进行多集或元组列表。 (Char,Int),然后我必须编写一个函数,该函数接受一个项目并将其插入到此列表中,但是如果列表中已经有匹配的元组,则会增加Int。 即我有一个列表[[p,2),(w,3)],我得到另一个w它应该给[[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

但这会带来很多错误,我需要在此时删除列表元素,并用(c,i + 1)替换它,那么如何从列表中删除列表以及如何获取i + 1? 还如何使循环遍历列表中的所有元素? 我不能使用任何导入数据的东西,我知道这很麻烦,但是任何帮助将非常感谢。

好的,可以将这段代码弄成乱七八糟,这样它就可以用于制作任何项目的元组,而不仅仅是char。 所以我可以加载它,并用stuntngs创建一个元组列表,关闭它,然后再次加载它,并创建一个int元组列表?

好的,我认为您的想法不错,您只需弄清楚细节即可。

您询问的循环通常是通过递归完成的(因为列表是一个很好的递归结构),或者使用一些更高阶的函数(例如mapfilterfoldr ,...)来隐藏递归(您可以说他们抽象出重复的内容)-在这种情况下,我认为最简单的方法就是按照您开始的内容进行操作并使用直接递归。

这是一个执行基本操作的简单版本(您可能想要扩展):

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

如您所见,第一种情况与您的情况非常相似:如果字典(第二个参数)为空列表,则只需添加一个新的元组,并插入ch​​ar和数字1

如果不是,则检查字典中的第一个元素是否具有相同的字符(此处为c' );如果是,则增加计数;如果不是,则让该元素保持原状并递归搜索字典的其余部分。

还要注意,您可以在此处使用模式匹配,不仅将字典解构为head::tail形式,而且还可以将head解构为(..,..)元组部分。

如果需要,可以在其中使用@并获得第二种情况的简洁性:

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

对于初学者来说,仅具有递归功能的列表操作确实很难,但是在这种情况下,它们应该很好地解决了这个问题。

让我们从更好的签名和助手开始。

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

好的,现在我们将“正确的”部分分成第一部分和其余部分。 让我们看一下if

  • 如果我们设法找到该元素,则可以通过将列表的其余部分附加到修改后的元素以及我们之前拥有的元素来结束计算
  • 如果仍然不是,我们进行递归。

作为最后的补充,您可以轻松地将Char更改为Eq a => a以使您的函数可以处理任何可以直接比较的类型,包括Char

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM