2016-02-11 2 views
2

J'écris une fonction Haskell qui prend une chaîne et remplace tous les caractères en double dans la chaîne avec '_'. Jusqu'à présent, j'ai ceci:Remplacer les doublons char dans la chaîne avec '_'

markDups :: [Char] -> [Char] 
markDups = dupsHelp [] 
where dupsHelp c [] = c 
     dupsHelp c (x:xs) 
      | x `elem` c = dupsHelp c xs 
      | otherwise = dupsHelp (C++ [x]) xs 

Le code supprime les caractères répétitifs.

Exemple: "Bonjour tout le monde" -> "Helo Wrd"

Comment puis-je modifier ce code pour obtenir "Hel_o W_r_d"? Je vous remercie.

Répondre

1

Il est assez simple:

markDups :: [Char] -> [Char] 
markDups = dupsHelp [] 
where dupsHelp c [] = c 
     dupsHelp c (x:xs) 
      | x `elem` c = dupsHelp (C++ "_") xs 
--        ~~~~~~~~~~ 
      | otherwise = dupsHelp (C++ [x]) xs 

Au lieu de jeter simplement x, vous défaussez x et le remplacer par '_'.

Vous pouvez également exprimer avec un pli gauche:

import Data.List (foldl') 

markDups = reverse . snd . foldl' go ([], []) 
    where 
    go (seen, acc) c = 
    (c : seen   -- Add character to seen duplicates for next step. 
    , if c `elem` seen -- If character is in duplicates: 
     then '_' : acc -- Add an underscore to result. 
     else c : acc  -- Otherwise, just add the character. 
    ) 
+0

Merci beaucoup! – JMV12

2

Vous n'avez pas besoin de stocker les caractères déjà vus. Vous pouvez simplement supprimer toutes les occurrences de votre personnage du reste de la chaîne:

markDups :: [Char] -> [Char] 
markDups []  = [] 
markDups ('_':xs) = '_' : markDups xs 
markDups (x :xs) = x : markDups (map mark xs) 
    where 
    mark y = if x == y then '_' else y