2012-08-27 3 views
1

최근에 나는 다른 단어의 글자에서 단어를 만드는 단어 게임을 만들기 시작했습니다. 예를 들어 "게르만 어"라는 단어가있는 경우 "강장제", "음색"등을 만들 수 있습니다. 게임에서는 단어에서 사용 가능한 문자 만 사용할 수 있으며 반복하지는 않습니다. 즉, 위의 예에서 "강장제"가 유효하지만 "강북"에는 단 하나의 "오"만 있기 때문에 "강모"는 아닙니다.X에서 단어의 모든 문자와 일치하는 정규식을 만들려면 어떻게해야합니까?

내 질문은 기본적으로 정규 표현식을 만들어서 문자 인스턴스를 검색하고 나중에 루프에서 같은 문자를 사용하면 다시 찾지 않도록 기억합니다. ?

"Teutonic"이 있고 "tonico"("t", "o", "n", "i", "c", "o")의 각 문자에 대해 정규식을 사용하여 검색하는 경우 마지막 "o"를 제외하고는 모든 사람에게 "사실"을 얻을 것입니다.

"연필"이라는 단어가있는 경우 "펜", "라인"및 "더미"에는 적용되지만 "파이프"에는 적용되지 않습니다.

"작음"이있는 경우 "몰", "몰"은 표시되지만 "질량"은 표시되지 않습니다.


편집 :

는 당신에게 당신의 프롬프트 응답의 모든 주셔서 대단히 감사합니다! 저는 정규식 접근법으로는 가능하지 않을 것이라고 생각했지만, 저는 확신하고 싶었습니다. 대신, 나는 배열 방법으로 조금 실험했다. 나는별로 멀지 않았다.

다시 한 번 감사드립니다.

+1

나는 정규식 문제가 해결되지 것이라 생각합니다. 알고리즘에 대한 답변이 충분합니까? 그렇다면 뭔가 쓸 것입니다. – davidbuzatto

+0

@ Fabrício Matté : 수치 스러움 : -S – zerkms

+0

@xdazz : 누군가 1 개 이상의 프로그래밍 언어를 사용할 수 있다는 것을 깨달을 필요가 있습니다. -S – zerkms

답변

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'); 
+1

[fiddle] (http://jsfiddle.net/ult_combo/tBFEZ/), 좋은 논리. –

+0

해시 기반 접근 방식이이 문제에 더 유리하다고 생각합니다. 특히 게임에서 많은 단어를 고정 된 소스와 비교해야하기 때문에. 해시를 사용하는 것이 더 빠르며 장소 전체에서 문자열을 분할하고 연결하는 것보다 훨씬 깔끔합니다. – verdesmarald

+0

해시 기반 접근 방식은 대형 배열의 경우 더 좋을 것입니다. 해시 테이블을 만드는 작업에 약간의 오버 헤드가 있으며 단일 단어의 경우에는 맞지 않습니다. – Gabber

0

정규식에 적합한 유스 케이스인지 잘 모르겠습니까? 제 생각에 당신은 원어로 된 글자들을 다른 순서대로 사용하기를 원하기 때문에 그 표현은 더 이상 "규칙적인"것이 아닙니다.

내가 할 수 있으면 매우 복잡한 역 참조를 사용해야 할 것입니다.

저는 일종의 사용자 지정 (또는 기존 도메인 특정) 알고리즘을 사용하여 개인적으로이를 공격합니다.

하지만 나는 정규 표현식 전문가가 아니라는 것을 인정해야한다.

2

정규식은이 작업에 적합하지 않습니다. 소스 및 대상 문자열에 대해 (character -> occurrences)의 해시를 작성한 다음 대상 해시의 개수를 비교하여 모두 < = 소스 해시의 해당 개수인지 확인하십시오.

하면 객체에이 논리를 고수하는 경우, 당신은 한 번만 소스 해시를 구축 한 다음에 테스트 할 수 있습니다 여러 번 (jsFiddle version는) :

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 
+0

감사합니다! 전에 해시로 작업 한 적이 없으므로이 문제를 조사하고 테스트 해 보겠습니다. – Sele

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; 

*/ 
+0

닉이 정확하고 올바르지 않습니까? – Gabber

관련 문제