Haskell - 从列表中删除相邻的重复项 [英] Haskell - Removing adjacent duplicates from a list

查看:165
本文介绍了Haskell - 从列表中删除相邻的重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过解决一些在线问题和培训练习来学习haskell。

现在我正在尝试创建一个函数来删除相邻的重复项来自列表。


样本输入



acvvca



1456776541



abbac



aabaabckllm






预期产量





c



ckm


我的第一个过程是创建一个函数,它只是删除相邻副本的第一个实例并恢复列表。

  module Test where 

removeAdjDups ::(Eq a)=> [a] - > [a]
removeAdjDups [] = []
removeAdjDups [x] = [x]
removeAdjDups(x:y:ys)
| x == y = removeAdjDups ys
|否则= x:removeAdjDups(y:ys)






  *试验> removeAdjDups1233213443
122133






这个函数适用于第一个找到的对。



所以现在我需要对函数的结果应用相同的函数。

我认为foldl可以提供帮助,但我不知道如何去实现它。



  removeAdjDups'xs = foldl(\acc x  - > removeAdjDups x acc)xs 






此方法是实现解决方案的最佳方式,还是我应该考虑的更好方法?

解决方案

从最后一位开始:首先从尾部删除重复项,然后检查输入的头是否等于头尾部结果(到目前为止,它不会有任何重复,所以唯一可能的对是尾部结果的头部与尾部的头部):

  main = mapM_(print。squeeze)[acvvca,1456776541,abbac,aabaabckllm] 

squeeze :: Eq a => ; [a] - > [a]
squeeze(x:xs)= let ys =挤压xs,如果
(y:ys')的ys | x == y - > ys'
_ - > x:ys
squeeze _ = []

输出

 

c
ckm


I'm trying to learn haskell by solving some online problems and training exercises.

Right now I'm trying to make a function that'd remove adjacent duplicates from a list.

Sample Input

"acvvca"

"1456776541"

"abbac"

"aabaabckllm"


Expected Output

""

""

"c"

"ckm"

My first though was to make a function that'd simply remove first instance of adjacent duplicates and restore the list.

module Test where

removeAdjDups :: (Eq a) => [a] -> [a]
removeAdjDups []           =  []
removeAdjDups [x]          =  [x]
removeAdjDups (x : y : ys)
  | x == y = removeAdjDups ys
  | otherwise = x : removeAdjDups (y : ys)


*Test> removeAdjDups "1233213443"
"122133"


This func works for first found pairs.

So now I need to apply same function over the result of the function.

Something I think foldl can help with but I don't know how I'd go about implementing it.

Something along the line of

removeAdjDups' xs = foldl (\acc x -> removeAdjDups x acc) xs


Also is this approach the best way to implement the solution or is there a better way I should be thinking of?

解决方案

Start in last-first order: first remove duplicates from the tail, then check if head of the input equals to head of the tail result (which, by this moment, won't have any duplicates, so the only possible pair is head of the input vs. head of the tail result):

main = mapM_ (print . squeeze) ["acvvca", "1456776541", "abbac", "aabaabckllm"]

squeeze :: Eq a => [a] -> [a]
squeeze (x:xs) = let ys = squeeze xs in case ys of
                                            (y:ys') | x == y -> ys'
                                            _ -> x:ys
squeeze _ = []

Outputs

""
""
"c"
"ckm"

这篇关于Haskell - 从列表中删除相邻的重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆