1

最近、別の単語の文字から単語を作る単語ゲームを作り始めました。たとえば、"Teutonic" という単語がある場合、"tonic"、"tone" などを作成できます。ゲームでは、単語で使用できる文字のみを使用でき、それらを繰り返すことはできません。つまり、上記の例では "tonic" は有効ですが、"tonic" は有効ではありません。これは、"Teutonic" には "o" が 1 つしかないためです。

私の質問は基本的に、文字の1 つのインスタンスを検索し、それを記憶して、ループの後半で同じ文字が与えられた場合に再度検索しないように、正規表現を作成するにはどうすればよいですか?

したがって、"Teutonic" があり、"tonico" の各文字 ("t"、"o"、"n"、"i"、"c"、"o") を正規表現で検索すると、次のようになります。最後の「o」を除いて、すべて「true」。

「鉛筆」という単語がある場合、「ペン」、「線」、「パイル」には当てはまりますが、「パイプ」には当てはまりません。

または、「小さい」がある場合、「モール」、「モール」には当てはまりますが、「マス」には当てはまりません。


編集:

早速のお返事ありがとうございます!正規表現のアプローチでは不可能だと思っていましたが、確認したかったのです。代わりに、配列メソッドを少し試してみましたが、あまりうまくいかないと思いました。

みんなありがとう!

4

4 に答える 4

6

文字列を配列に分割し、配列と比較します。

function checkStr(str1, str2) {
  var arr1 = str1.split(''),
      arr2 = str2.split(''),
      i,j;
  for (i = 0; i < arr2.length; i++) {
     if ((j= arr1.indexOf(arr2[i])) === -1) {
        return false;
     } 
     arr1.splice(j, 1);
  }
  return true;
}
// usage
checkStr('small', 'mall');
于 2012-08-27T04:08:20.203 に答える
2

正規表現は、このタスクには適していません。ソース文字列とターゲット文字列のハッシュを(character -> occurrences)作成し、ターゲット ハッシュのカウントを比較して、すべて <= ソース ハッシュの対応するカウントであることを確認します。

このロジックをオブジェクトに貼り付けると、ソース ハッシュを 1 回だけ作成し、それに対して複数回テストできます ( jsFiddle バージョン)。

function Comparer(sourceStr)
{
    this.buildHash = function(str)
    {
        var hash = new Object();
        for (var i in str)
            hash[str[i]] = (hash[str[i]] || 0) + 1;

        return hash
    };

    this.check = function(testStr)
    {
        var hash = this.buildHash(testStr);

        for (var c in hash)
            if ((this.sourceHash[c] || 0) < hash[c])
                return false;

        return true;
    };     

    this.source = sourceStr;
    this.sourceHash = this.buildHash(sourceStr);
};

var comp = new Comparer("teutonic");
alert(comp.check("tonic"));  // true
alert(comp.check("tint"));   // true
alert(comp.check("tonico")); // false
alert(comp.check("asdf"));   // false
于 2012-08-27T04:53:27.200 に答える
0
// It may not matter, but you can also compare strings without creating arrays.

String.prototype.contains= function(word){
    var seed= String(this), i= 0, len= word.length, next= '';
    while(i<len){
        next= word.charAt(i++);
        if(seed.indexOf(next)== -1) return false;
        seed= seed.replace(next, '');
    }
    return word;
}


//testing 
var startword= 'teutonic',report='startword= '+startword, 
list= ['ton', 'on', 'out', 'tout', 'tone', 'tonic', 'tune', 'nice', 
'note', 'not','tot', 'tote', 'ice', 'tic', 'nick', 'cone', 'con', 'cut', 'cute'];

var failed=list.filter(function(itm){
    return !startword.contains(itm);
});

report+= failed.length? '\n'+failed.length+' incorrect: '+failed+';\n':'';
report+=list.length+' correct: '+list+';\n';
alert(report);


/*  returned value: (String)
startword= teutonic
1 incorrect: nick;
19 correct: ton,on,out,tout,tone,tonic,tune,nice,note,
not,tot,tote,ice,tic,nick,cone,con,cut,cute;

*/
于 2012-08-27T06:34:25.257 に答える
0

これが正規表現の適切なユースケースかどうかよくわかりません。元の単語の文字を、表示される順序とは異なる順序で使用しようとしているため、表現はもはや「規則的」ではないと思います。

それができるとしたら、非常に複雑な後方参照を使用する必要があると思います。

私は、ある種のカスタム (または既存のドメイン固有) アルゴリズムを使用して、これを個人的に攻撃します。

しかし、私は正規表現の専門家ではないことを認めなければならないので、間違っていることが証明されてうれしいです!

于 2012-08-27T04:04:41.080 に答える