2014-11-07 4 views
0

반복을 통해 가능한 모든 변형을 나열하는 함수를 만들려고합니다. 내가 만든 것은 "너무 많은 재귀"를 반환합니다."반복되는 너무 많은 재귀"변형

function variants(amount, chars, junk){ 
    var junkarray = junk.split(","); 
    var newjunk; 
    if(junkarray[junkarray.length-1]==amount){ 
     newjunk = ","; 
    } 
    if(junk.length==Math.pow(chars.length, amount)){ 
     console.log(junk); 
     return; 
    }else{ 
     for(var i = 0; i < chars.length; i++){ 
      variants(amount, chars, junk+newjunk+chars[i]); 
     } 
    } 
} 
variants(3, ["1", "2"],""); 
+0

귀하의 스 니펫이 내 탭을 추락 시켰습니다. 나는 당신이 그것을 제거해야한다고 생각합니다. –

+0

: D 그래, 당신은 프로 대가입니다. "너무 많은 재귀"를 발생시키는 경우 실행 가능한 스 니펫을 만드는 이유는 무엇입니까? – nicael

+0

예상되는 입출력이 무엇이되어야하는지 설명 할 수 있습니까? –

답변

1

Ingo Bürk의 답변에서 왜 무한 재귀가 발생했는지에 대해 설명하지만 다소 다른 문제를 해결합니다. 이것은 또한 너무 큰 데이터를 재귀 문제로 실행됩니다,하지만 당신은 데이터의 비교적 작은 세트의 잘해야한다는

var variants = function(amount, chars, soFar) { 
    soFar = soFar || [""]; 
    if (amount === 0) {return soFar;} 
    var partials = soFar.map(function(partial) { 
     return chars.map(function(char) { 
      return partial.concat(char); 
     }); 
    }).reduce(function(a, b) {return a.concat(b);}, []); 
    return variants(amount - 1, chars, partials); 
}; 

var v = variants(3, ["1", "2"]); 
//=> ["111", "112", "121", "122", "211", "212", "221", "222"] 

참고 : 여기에 작동하는 것 같다 하나 개의 솔루션 (Fiddle)입니다.

업데이트

은 아마 조금 청소기는 재귀 호출을 위해 내부적으로 사용되어야하는 세 번째 매개 변수, 그래서 this Fiddle이 조금 더 나은 얻을 수를 발표하지 않을 것이라고 생각 :

var variants = function(amount, chars) { 
    var soFar = arguments[2] || [""]; 
    // ... no other changes. 
} 
3

귀하의 문제는 절대로 exit 절에 도달하지 않아서 무한 재귀가 발생한다는 것입니다. 문제는 여기에있다 : 당신은 아무것도 newjunk를 초기화하지 않고 그것을 설정하는 기회가있는 부분에 생략하는 경우 그래서 당신의 변수가 정의되지 않은 남아

var newjunk; 
... 
variants(amount, chars, junk+newjunk+chars[i]); 

. 그래서 문자열을 else 절의 다른 변수에 연결할 때 js는 "undefined"값을 "undefined"문자열로 변환합니다. 이 줄을 잘라내어 붙여 넣으려면 다음 줄을 사용하십시오.

var newjunk; var junk = ""; var chars = ["1","2"]; console.log(result, junk+newjunk+chars[0]); 

좋아하는 콘솔에 붙여 넣으십시오. undefined1을 출력합니다. 그것을 해결하는 방법은 빈 문자열로 newjunk을 초기화하기 위해서입니다 :

여기
var newjunk = "" 

이 변화의 jsfiddle입니다.

재귀 문제를 디버깅하는 좋은 방법은 종이와 펜을 떼어내어 각 코드 행을 물리적으로 추적하여 exit 절이 맞는지 확인하는 것입니다. 전역 카운트 변수의 형식으로 조기 종료 조건을 추가하여 함수 내에서 증가시킬 수도 있습니다. 이 카운트 변수가 특정 값에 도달하면 종료합니다.