文 B の文 A から削除された単語を確認する場合、Java での最善のアプローチは何ですか。たとえば、次のようになります。
文 A: この簡単な文で不要な単語を削除したい.
文 B: この文の単語を削除したいです。
出力: この (単純な) 文の (不要な) 単語を削除したい。
ここで、括弧内の単語は文 A から削除された単語です。
順序は問題ではないと仮定すると、commons-collections を使用します。
String.split()
両方の文を単語の配列に分割するために使用します。CollectionUtils.addAll
して、各配列を空の に追加しますSet
。CollectionUtils.subtract
メソッドを使用して AB を取得します。String a = "I want to delete unnecessary words on this simple sentence.";
String b = "I want to delete words on this sentence.";
String[] aWords = a.split(" ");
String[] bWords = b.split(" ");
List<String> missingWords = new ArrayList<String> ();
int x = 0;
for(int i = 0 ; i < aWords.length; i++) {
String aWord = aWords[i];
if(x < bWords.length) {
String bWord = bWords[x];
if(aWord.equals(bWord)) {
x++;
} else {
missingWords.add(aWord);
}
} else {
missingWords.add(aWord);
}
}
順序と位置が重要であると仮定すると、これは、動的計画法のソリューションである最長共通サブシーケンス問題のバリエーションのように見えます。
ウィキペディアにはこのトピックに関するすばらしいページがあります。ここで概説するにはあまりにも多くのことがあります
http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
他の誰もが、実際には非常に単純な問題に対して、非常に重いアルゴリズムを使用しています。最長共通部分列を使用して解決できますが、それは非常に制限されたバージョンです。完全な差分ではありません。削除のみが含まれます。動的プログラミングなどは必要ありません。以下は 20 行の実装です。
private static String deletedWords(String s1, String s2) {
StringBuilder sb = new StringBuilder();
String[] words1 = s1.split("\\s+");
String[] words2 = s2.split("\\s+");
int i1, i2;
i1 = i2 = 0;
while (i1 < words1.length) {
if (words1[i1].equals(words2[i2])) {
sb.append(words1[i1]);
i2++;
} else {
sb.append("(" + words1[i1] + ")");
}
if (i1 < words1.length - 1) {
sb.append(" ");
}
i1++;
}
return sb.toString();
}
入力が問題のものである場合、出力は正確に一致します。
確かに、一部の入力には複数のソリューションがあることは理解しています。例えば:
a b a
a
この問題のいくつかのバージョンでは、これらのソリューションの1つが他のソリューションよりも「実際の」ソリューションである可能性が高く、再帰的または動的なプログラミングアプローチが必要な場合は...しかし、それを行わないようにしましょa (b) (a)
う(a) (b) a
イスラエル・サトウが最初に求めたものよりも複雑すぎる!
これは基本的に異なります。これを見てください。
そしてルートアルゴリズム:
サンプルの Java 実装を次に示します。
行を比較します。必要なのは、行ごとではなく単語ごとに分割するか、両方の文の各単語を別の行に入れることだけです。
たとえばLinuxで、diff
コードを書く前にプログラム自体を使用して後者のオプションの結果を実際に確認できる場合は、これを試してください。
$ echo "I want to delete unnecessary words on this simple sentence."|tr " " "\n" > 1
$ echo "I want to delete words on this sentence."|tr " " "\n" > 2
$ diff -uN 1 2
--- 1 2012-10-01 19:40:51.998853057 -0400
+++ 2 2012-10-01 19:40:51.998853057 -0400
@@ -2,9 +2,7 @@
want
to
delete
-unnecessary
words
on
this
-simple
sentence.
前にある行-
は異なります (または、+
行が文 A になかった文 B に追加された場合に表示されます)。それがあなたの問題に合っているかどうかを確認するために試してみてください。
お役に立てれば。