Zeigen Sie eine Liste von Wörtern in Haskell wiederholt
Frage
Ich muss in der Lage, eine Funktion zu schreiben, die Worte aus einem String und eine Liste von Zeichenfolgen in der Reihenfolge ihres Auftretens und ignorieren nicht-Buchstaben
wiederholt zeigtz bei Umarmungen Prompt
repetitions :: String -> [String]
repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]
Lösung
eine Zeichenfolge in Worte zu verteilen, verwenden Sie die words
Funktion (im Prelude).
Zur Beseitigung Nicht-Wort-Zeichen filter
mit Data.Char.isAlphaNum
.
Zip die Liste zusammen mit seinem Schwanz benachbarter Paare (x, y)
zu bekommen.
Falten Sie die Liste, consing eine neue Liste, die alle x
enthält, wo x
== y
.
Someting wie:
repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
where l = map (filter isAlphaNum) (words s)
Ich bin nicht sicher, ob das funktioniert, aber es sollte Ihnen eine grobe Vorstellung geben.
Andere Tipps
Ich bin neu in dieser Sprache so meine Lösung eine Art hässlich in den Augen eines Haskell Veteran sein könnte, aber trotzdem:
let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))
Dieser Teil wird alle nicht Buchstaben und nicht Leerzeichen aus einem String entfernen s :
filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') s
Dieser wird geteilt eine Zeichenfolge s , um Wörter und Gruppe die gleichen Worte Listen Rückkehr Liste der Listen:
List.group (words s)
Wenn dieser Teil werden alle Listen mit weniger als zwei Elemente entfernen:
filter (\x -> (length x) > 1) s
Nach dem, was wir alle Listen auf ein verketten Entfernen eines Elements aus ihnen obwohl
concat (map tail s)
Dies könnte inelegent, aber es ist vom Konzept her sehr einfach ist. Ich gehe davon aus, dass seine für aufeinanderfolgende doppelte Wörter wie die Beispiele suchen.
-- a wrapper that allows you to give the input as a String
repititions :: String -> [String]
repititions s = repititionsLogic (words s)
-- dose the real work
repititionsLogic :: [String] -> [String]
repititionsLogic [] = []
repititionsLogic [a] = []
repititionsLogic (a:as)
| ((==) a (head as)) = a : repititionsLogic as
| otherwise = repititionsLogic as
Aufbauend auf Alexander Prokofyev antwortete:
repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))
Entfernen Sie unnötige Klammern:
repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))
$ verwenden, um weitere Klammer zu entfernen (jeweils $ eine öffnende Klammer ersetzen kann, wenn die Endung Klammer am Ende des Ausdrucks ist):
repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x
Ersetzen Zeichenbereiche mit Funktionen aus Data.Char, fusioniert concat und Karte:
repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x
Verwenden Sie einen Abschnitt und Striegeln in Punkten freien Stil (\x -> length x > 1) to ((>1) . length)
zu vereinfachen. Dies kombiniert mit length
(> 1) (einem teilweise Applied Operator oder Abschnitt ) in einem Rechts-nach-links-Pipeline.
repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x
beseitigen explizite "x" Variable Gesamtausdruck Punkte frei zu machen:
repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)
nun die gesamte Funktion von rechts liest, nach links ist eine Rohrleitung, die nur alpha- oder Trennzeichen filtert, teilt sie in Worte, bricht es in Gruppen, filtert diese Gruppen mit mehr als 1 Elemente, und reduziert dann die restlichen Gruppen auf das erste Element eines jeden.