2017-02-27 46 views
1

我想要更好地理解遞歸,並試圖使用常見的'Fizzbuzz'問題創建一個包含數字的數組。我試圖通過僅使用一個輸入實現一個純遞歸函數來實現這一點,但我無法讓我的答案以正確的順序出現。我也很想知道是否有一種方法來編寫一個純粹的遞歸函數,在這種情況下使用push而不是concat。任何幫助表示讚賞!我能夠打印出所需的輸出,但是以相反的順序進行。以下是我到目前爲止:Javascript - 使用純遞歸函數創建一個帶有FizzBu​​zz結果的數組

var fizzBuzz = function(n) { 
    //create results array 
    //create base case for when n === 1 
    //recurse and push value to array 
    var results = []; 
    if (n === 1) { 
    return '1'; 
    } else { 
    if (n % 3 === 0 && n % 5 === 0) { 
     results.push('FizzBuzz'); 
    } else if (n % 5 === 0) { 
     results.push('Buzz'); 
    } else if (n % 3 === 0) { 
     results.push('Fizz'); 
    } else { 
     results.push(''+ n); 
    } 
    return results.concat(fizzBuzz(n - 1)); 
    } 
}; 
+0

你必須reverese在年底陣! –

回答

2

有很多方法可以做到這一點,這取決於您的要求。

一個最簡單的辦法就是扭轉你的陣列中底:

function fizzBuzz(n) { 
 
    function fizzBuzzRecursive(n) { 
 
    //create results array 
 
    //create base case for when n === 1 
 
    //recurse and push value to array 
 
    var results = []; 
 
    if (n === 1) { 
 
     return '1'; 
 
    } else { 
 
     if (n % 3 === 0 && n % 5 === 0) { 
 
     results.push('FizzBuzz'); 
 
     } else if (n % 5 === 0) { 
 
     results.push('Buzz'); 
 
     } else if (n % 3 === 0) { 
 
     results.push('Fizz'); 
 
     } else { 
 
     results.push(''+ n); 
 
     } 
 
     return results.concat(fizzBuzzRecursive(n - 1)); 
 
    } 
 
    } 
 
    
 
    return fizzBuzzRecursive(n).reverse(); 
 
}; 
 

 
console.log(fizzBuzz(15));

它可能看起來很醜陋,但它與代碼(有時,它是最小的改動來解決你的問題一個關鍵要求)。

另一種解決方法是將fizzBuzzRecursive連接到您的results。請注意,爲了使其正常工作,您需要返回[1]而不是"1"代替n == 1,以便JS將第一個結果解釋爲數組而不是字符串。

function fizzBuzz(n) { 
 
    //create results array 
 
    //create base case for when n === 1 
 
    //recurse and push value to array 
 
    var results = []; 
 
    if (n === 1) { 
 
    return ['1']; // ! 
 
    } else { 
 
    if (n % 3 === 0 && n % 5 === 0) { 
 
     results.push('FizzBuzz'); 
 
    } else if (n % 5 === 0) { 
 
     results.push('Buzz'); 
 
    } else if (n % 3 === 0) { 
 
     results.push('Fizz'); 
 
    } else { 
 
     results.push(''+ n); 
 
    } 
 
    return fizzBuzz(n - 1).concat(results); 
 
    } 
 
}; 
 

 
console.log(fizzBuzz(15));

第三個解決辦法是改變你的遞歸函數,使其在一個相反的順序進行迭代。你可以自己試試吧:)

+0

非常感謝Yeldar!我的目標是實現一個不使用內部函數的解決方案,所以這非常有用。快樂的編碼! –

0

另一種解決方案,從0(有點)迭代:https://repl.it/FysV/1

var hold = 0; 
var fizzBuzz = function(n) { 
    var results = []; 

    if(hold === n) return '' + n; 

    if(hold === 0) { 
    hold = n; 
    n = 1; 
    } 

    if (n === 1) { 
    results.push('1'); 
    } else if (n % 3 === 0 && n % 5 === 0) { 
    results.push('FizzBuzz'); 
    } else if (n % 5 === 0) { 
    results.push('Buzz'); 
    } else if (n % 3 === 0) { 
    results.push('Fizz'); 
    } else { 
    results.push(''+ n); 
    } 

    return results.concat(fizzBuzz(n + 1)); 
} 
0

第一種方法:通過數組作爲parametter

var fizzBuzz = function(n, arr = []) { // fizzBuzz should have two params: the number n and the accumulated array arr 
 
    
 
    // if you don't like the arr = [] in the parametter, or if it's not supported then just declare arr as a regular argument (function(n, arr)) and uncomment the following line to check if the array is passed or not (in the first call) 
 
    // arr = arr || []; 
 
    
 
    if (n === 1) {       // if n is 1 then add 1 to the array and return its inverse because we didn't fuzzBuzz in the right order 
 
    arr.push('1'); 
 
    return arr.reverse(); 
 
    } else {        // logic blah blah ... 
 
    if (n % 3 === 0 && n % 5 === 0) { 
 
     arr.push('FizzBuzz'); 
 
    } else if (n % 5 === 0) { 
 
     arr.push('Buzz'); 
 
    } else if (n % 3 === 0) { 
 
     arr.push('Fizz'); 
 
    } else { 
 
     arr.push('' + n); 
 
    } 
 
    return fizzBuzz(n - 1, arr);   // no need to use concat because we are passing the acummulated array to append to it 
 
    } 
 
} 
 

 
console.log(fizzBuzz(10));

第二種方法:內部功能函數clossures

var fizzBuzz = function(n) { 
 
    var arr = [];      // the array 
 
    
 
    function fizzBuzzInternal(i) {  // the real fizzBuzz function 
 
    if (i % 3 === 0 && i % 5 === 0) { // logic blah blah ... 
 
     arr.push('FizzBuzz'); 
 
    } else if (i % 5 === 0) { 
 
     arr.push('Buzz'); 
 
    } else if (i % 3 === 0) { 
 
     arr.push('Fizz'); 
 
    } else { 
 
     arr.push('' + i); 
 
    } 
 
    
 
    if(i < n)       // if i is still less than n then invoke another fizzBuzzInternal call 
 
     fizzBuzzInternal(i + 1); 
 
    } 
 
    
 
    fizzBuzzInternal(1);    // invoke the first fizzBuzzInternal to start the show 
 
    
 
    return arr;       // return the array (no need for inversing because we fizzBuzzed in the right direction) 
 
} 
 

 
console.log(fizzBuzz(10));