2013-10-23 17 views
5

Supponendo che avessi la stringa "CIAO MONDO" c'è un modo per chiamare una funzione che sostituisce il carattere 'O' nella stringa con il carattere 'X' in modo che la nuova stringa assomigli "HELLX WXRLD"?Haskell sostituisce i caratteri nella stringa

+1

possibile duplicato di [? Come posso sostituire una sottostringa di una stringa con un'altra in Haskell senza utilizzare librerie esterne come MissingH] (http://stackoverflow.com/questions/14880299/how-can-i-replace-a-substring-of-a-string-with-another-in-haskell-without-using) – Orbling

+6

Hai cercato a tutti come questa domanda è arrivata più volte. – Orbling

risposta

26

ne dite:

let 
    repl 'o' = 'x' 
    repl c = c 
in map repl "Hello World" 

Se è necessario sostituire i caratteri in un secondo momento, è sufficiente aggiungere clausole alla funzione repl.

+0

Oh, capisco. La mia soluzione è davvero un po 'complicata. –

+2

La corrispondenza del modello è re. – reem

+0

Puoi farlo con un lambda in una riga? Se è così, un altro +1 da me :) – vikingsteve

1

Ecco un'altra soluzione possibile utilizzando divide et impera:

replaceO [] = [] 
replaceO (x:xs) = 
    if x == 'O' 
    then 'X' : replaceO xs 
    else x : replaceO xs 

In primo luogo, si imposta la condizione di bordo "replaceO [] = []".
Se la lista è vuota, non c'è nulla da sostituire, restituendo una lista vuota.

Successivamente, prendiamo lo spago e lo dividiamo in testa e coda. in questo caso 'H':"ELLOWORLD"
Se la testa è uguale a "O", la sostituirà con "X". e applicare la funzione replaceO al resto della stringa.
Se la testa non è uguale a "O", riporterà la testa indietro dove si trova e applicherà la funzione replaceO al resto della stringa.

9

Siamo spiacenti per la raccolta di questo thread precedente, ma perché non utilizzare le espressioni lambda?

λ> let replaceO = map (\c -> if c=='O' then 'X'; else c) 
λ> replaceO "HELLO WORLD" 
"HELLX WXRLD"` 
-2

Immagino che possa essere utile.

main = print $ charRemap "Hello WOrld" ['O','o'] ['X','x'] 

charRemap :: [Char] -> [Char] -> [Char] -> [Char] 
charRemap [] _ _ = [] 
charRemap (w:word) mapFrom mapTo = 
    if snd state 
     then mapTo !! fst state : charRemap word mapFrom mapTo 
     else w : charRemap word mapFrom mapTo 
    where 
     state = hasChar w mapFrom 0 

hasChar :: Char -> [Char] -> Int -> (Int,Bool) 
hasChar _ [] _ = (0,False) 
hasChar c (x:xs) i | c == x = (i,True) 
        | otherwise = hasChar c xs (i+1) 
3

Alternativa 1 - Utilizzando MissingH

Primo:

import Data.List.Utils (replace) 

Quindi utilizzare:

replace "O" "X" "HELLO WORLD" 

Alternativa 2 - Utilizzare Control.Monad

Un bastardo divertente:

import Control.Monad (mfilter) 

replace a b = map $ maybe b id . mfilter (/= a) . Just 

Esempio:

λ> replace 'O' 'X' "HELLO WORLD" 
"HELLX WXRLD" 

Alternativa 3 - utilizzando se

suggerimenti di Amon era probabilmente la più bella credo! Nessuna importazione e facile da leggere e capire!

Ma per essere pignoli - non c'è bisogno di punto e virgola:

replace :: Eq a => a -> a -> [a] -> [a] 
replace a b = map $ \c -> if c == a then b else c 
Problemi correlati