Home > front end >  Eliminate consecutive duplicates from a string
Eliminate consecutive duplicates from a string

Time:01-20

I want to eliminate consecutive duplicates from a string like f "aaabbbcccdeefgggg" = "abcdefg"

This is my code

f :: String -> String
f "" = ""
f "_" = "_"
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)

I got as error non-exhaustive patterns, I think it's from second line, the program doesn't know how to deal when it's only 1 char left. How should I fix it?

CodePudding user response:

The "_" pattern does not match a string with any character, it matches the string that contains an underscore.

You can use [_] as pattern for the singleton string, so:

f :: String -> String
f "" = ""
f s@[_] = s
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)

here we use s@ to capture the string with one character as s.

or we can simplify this with:

f :: String -> String
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)
f s = s

CodePudding user response:

This is an answer to the "title" of your question.

You can just group the letters which are equal, and then take the first of each group:

map head $ Data.List.group "aaabbbcccdeefgggg"

For completeness, as you seem to be new to Haskell, here are a few details:

  • Data.List.group "aaabbbcccdeefgggg" returns ["aaa","bbb","ccc","d","ee","f","gggg"];
  • f $ a b c is the same as f (a b c);
  • if you import Data.List (group) or more generally import Data.List, then you can skip the Data.List. bit which fully qualifies group and use it unqualified: map head $ group "blaaa".

CodePudding user response:

Or you can make it even simpler if you don't handle things that can be left unhandled:

f :: String -> String
f (x:y:xs) | x == y = f (y:xs)
f (x:xs) = x:f xs
f _ = ""

CodePudding user response:

You also could use foldl. the logic is: comparing the last element of accumulator with current element.

f :: Eq a => [a] -> [a]
f xs = foldl (\x y -> if last x == y then x else x  [y] )  [head xs] xs

here we initiate our accumulator with [head x].

  •  Tags:  
  • Related