4

文字列から繰り返される単語を表示し、文字列のリストを出現順に返し、文字以外を無視する関数を作成できる必要があります

例:抱擁プロンプトで

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"]
4

4 に答える 4

8

文字列を単語に分割するには、words(プレリュード内の)関数を使用します。単語以外の文字を削除するにはfilterData.Char.isAlphaNum。リストをテールと一緒に圧縮して、隣接するペアを取得します(x, y)。リストを折りたたんで、すべてのxwhere x==を含む新しいリストを作成しますy

のような何か:

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
  where l = map (filter isAlphaNum) (words s)

それがうまくいくかどうかはわかりませんが、大まかなアイデアが得られるはずです。

于 2008-12-31T06:26:45.493 に答える
2

私はこの言語に慣れていないので、Haskellのベテランの目には私の解決策は一種の醜いものになる可能性がありますが、とにかく:

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)))))

この部分は、文字列sからすべての非文字および非スペースを削除します。

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') s

これは、文字列sを単語に分割し、同じ単語をリストにグループ化して、リストのリストを返します。

List.group (words s)

この部分が要素が 2 つ未満のすべてのリストを削除する場合:

filter (\x -> (length x) > 1) s

その後、すべてのリストを 1 つに連結し、それらから 1 つの要素を削除します

concat (map tail s)
于 2008-12-31T06:46:06.593 に答える
1

これは単純かもしれませんが、概念的には非常に単純です。例のように連続した重複する単語を探していると思います。

-- 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
于 2009-01-13T14:08:21.823 に答える
0

アレクサンダー・プロコフィエフの答えに基づいて:

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)))))

不要な括弧を削除します:

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)))))

$ を使用してさらに括弧を削除します (終わりの括弧が式の最後にある場合、各 $ は開き括弧を置き換えることができます)。

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

文字範囲を Data.Char の関数に置き換え、concat と map をマージします。

repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

単純化するために、ポイントフリー スタイルでセクションとカリー化を使用し(\x -> length x > 1) to ((>1) . length)ます。これは、右から左へのパイプラインlengthで (>1) (部分的に適用された演算子、またはセクション) と結合します。

repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

明示的な "x" 変数を削除して、式全体をポイントフリーにします。

repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)

右から左に読み取る関数全体は、アルファまたは区切り文字のみをフィルタリングし、それを単語に分割し、グループに分割し、複数の要素を持つグループをフィルタリングし、残りのグループを最初のグループに減らすパイプラインです。それぞれの要素。

于 2009-02-02T20:31:56.910 に答える