少なくとも1つの単語が同じである2つの文字列を一致させる必要があり、成功メッセージを与える必要があります。
var str1 = "Hello World";
var str2 = "world is beautiful";
これらの2つの文字列を一致/比較する必要があります。両方の文字列で世界が一致しているため、成功メッセージを出力する必要があります。どうすればいいですか。
少なくとも1つの単語が同じである2つの文字列を一致させる必要があり、成功メッセージを与える必要があります。
var str1 = "Hello World";
var str2 = "world is beautiful";
これらの2つの文字列を一致/比較する必要があります。両方の文字列で世界が一致しているため、成功メッセージを出力する必要があります。どうすればいいですか。
次のコードは、両方の文字列で一致するすべての単語を出力します。
var words1 = str1.split(/\s+/g),
words2 = str2.split(/\s+/g),
i,
j;
for (i = 0; i < words1.length; i++) {
for (j = 0; j < words2.length; j++) {
if (words1[i].toLowerCase() == words2[j].toLowerCase()) {
console.log('word '+words1[i]+' was found in both strings');
}
}
}
それぞれを並べ替えて重複を排除することにより、1 つのリスト内のすべての単語を他のリスト内のすべての単語と比較することを避けることができます。ビョルンドの答えを適応させる:
var words1 = str1.split(/\s+/g),
words2 = str2.split(/\s+/g);
var allwords = {};
// set 1 for all words in words1
for(var wordid=0; wordid < words1.length; ++wordid) {
var low = words1[wordid].toLowerCase();
allwords[low] = 1;
}
// add 2 for all words in words2
for(var wordid=0; wordid < words2.length; ++wordid) {
var current = 0;
var low = words2[wordid].toLowerCase();
if(allwords.hasOwnProperty(low)) {
if(allwords[low] > 1) {
continue;
}
}
current += 2;
allwords[low] = current;
}
// now those seen in both lists have value 3, the rest either 1 or 2.
// this is effectively a bitmask where the unit bit indicates words1 membership
// and the 2 bit indicates words2 membership
var both = [];
for(var prop in allwords) {
if(allwords.hasOwnProperty(prop) && (allwords[prop] == 3)) {
both.push(prop);
}
}
このバージョンは、各単語セットに関する情報を格納するために辞書/ハッシュ構造を使用しているため、かなり効率的です。すべてが JavaScript 式の O(n) ですが、必然的に辞書の挿入はそうではないため、実際には O(n log n) のようなものを期待してください。1 つの単語が一致することのみを気にする場合は、2 番目の for ループの早い段階で終了できます。コードはそのままで、すべての一致が検出されます。
これは、両方のリストを並べ替え、それぞれを一意の単語に減らし、両方のリストでペアを探すこととほぼ同じです。C++ などでは、辞書を使用せずに実行でき、並べ替え後の比較は O(n) になるため、2 つのセットを介して実行します。読みやすいのでPythonで:
words1 = set(item.lower() for item in str1.split())
words2 = set(item.lower() for item in str2.split())
common = words1 & words2
ここでの並べ替えは (他のセットと同様に) 単語数 n のセット O(n log n) への挿入時に発生し、交差 (&) はセットの長さ m で有効な O(m) になります。
WriteCodeOnlineでこれを試したところ、そこで機能します。
var s1 = "hello world, this is me";
var s2 = "I am tired of this world and I want to get off";
var s1s2 = s1 + ";" + s2;
var captures = /\b(\w+)\b.*;.*\b\1\b/i.exec(s1s2);
if (captures[1])
{
document.write(captures[1] + " occurs in both strings");
}
else
{
document.write("no match in both strings");
}
@Phil Hのコードを実際のビットマスクに適応させるだけです:
var strings = ["Hello World", "world is beautiful"]; // up to 32 word lists
var occurrences = {},
result = [];
for (var i=0; i<strings.length; i++) {
var words = strings[i].toLowerCase().split(/\s+/),
bit = 1<<i;
for (var j=0, l=words.length; j<l; j++) {
var word = words[j];
if (word in occurrences)
occurrences[word] |= bit;
else
occurrences[word] = bit;
}
}
// now lets do a match for all words which are both in strings[0] and strings[1]
var filter = 3; // 1<<0 | 1<<1
for (var word in occurrences)
if ((occurrences[word] & filter) === filter)
result.push(word);
OK、簡単な方法:
function isMatching(a, b)
{
return new RegExp("\\b(" + a.match(/\w+/g).join('|') + ")\\b", "gi").test(b);
}
isMatching("in", "pin"); // false
isMatching("Everything is beautiful, in its own way", "Every little thing she does is magic"); // true
isMatching("Hello World", "world is beautiful"); // true
...理解する?
基本的に"Hello, World!"
正規表現に変換しました/\b(Hello|World)\b/gi
このようなこともできます:
isMatching = function(str1, str2) {
str2 = str2.toLowerCase();
for (var i = 0, words = str1.toLowerCase().match(/\w+/g); i < words.length; i++) {
if (str2.search(words[i]) > -1) return true;
}
return false;
};
var str1 = "Hello World";
var str2 = "world is beautiful";
isMatching(str1, str2); // returns true
isMatching(str1, 'lorem ipsum'); // returns false