6

文字列に冒とく的な言葉が含まれているかどうかを確認する必要があります。

ここでの別の質問からのアドバイスに従って、次の単語を含むHashSetを作成しました。

HashSet<string> swearWords = new HashSet<string>() { "word_one", "word_two", "etc" };

次に、に含まれている値のいずれかがswearWords文字列に含まれているかどうかを確認する必要があります。

私はそれが逆に行われるのを見ました、例えば:

swearWords.Contains(myString)

しかし、これはfalseを返します。

HashSet内の単語のいずれかが含まれているかどうかを確認する最も速い方法は何myStringですか?

注意:foreachループを使用して各単語を順番にチェックし、一致するものが見つかった場合は中断できると思います。もっと速い方法があるかどうか疑問に思っています。

4

5 に答える 5

10

誓約をIEnumerable<>実装コンテナに配置する場合:

var containsSwears = swarWords.Any(w => myString.Contains(w));

注:HashSet<>はIEnumerable<>を実装します

于 2012-04-11T09:05:18.317 に答える
7

非常に多くの冒とく的な言葉がある場合は、Aho–Corasickアルゴリズムを使用できます:http://tomasp.net/blog/ahocorasick.aspx

于 2012-04-11T09:10:49.283 に答える
7

正規表現を試すこともできますが、それが速いかどうかはわかりません。

Regex rx = new Regex("(" + string.Join("|", swearWords) + ")");
rx.IsMatch(myString)
于 2012-04-11T09:06:21.217 に答える
4

このようなスキームの主な問題は、チェックする文字列のコンテキストで単語が何であるかを定義することです

  • を使用するような単純な実装input.Containsには、単語の概念がありません。それが意図されていなかったとしても、彼らは宣誓の言葉を「検出」します。
  • 空白の単語を壊しても、それをカットすることはできません(句読点なども考慮してください)。
  • 空白以外の文字を壊すと、文化の問題が発生します。正確には、どの文字が単語文字と見なされますか?

ストップワードリストでラテンアルファベットのみが使用されていると仮定すると、実用的な選択は、単語がラテン文字のみで構成されるシーケンスであると想定することです。したがって、合理的な開始ソリューションは次のようになります。

var words = Regex.Split(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Pc}\p{Lm}]", myString);

上記の正規表現は\W、数字を含まないように変更された標準クラスです。詳細については、http://msdn.microsoft.com/en-us/library/20bw873z.aspxを参照してください。他のアプローチについては、この質問と、受け入れられた回答で提供されているCodeProjectリンクを参照してください。

words入力文字列を分割したら、リスト内のすべてに一致するものを繰り返して置き換えるか(swearWords.Contains(word)チェックに使用)、一致するものがあるかどうかを単に検出することができます。

var anySwearWords = words.Intersect(swearWords).Any();
于 2012-04-11T09:20:37.410 に答える
3

「myString」をIEnumerable型に分割し、それらに「Overlaps」を使用できますか?

http://msdn.microsoft.com/en-us/library/bb355623(v=vs.90).aspx

(PS久しぶりです...)

編集:私の前の答えのエラーに気づきました。

于 2012-04-11T09:07:34.313 に答える