Javascript - 使用纯递归函数创建具有FizzBu​​zz结果的数组

时间:2017-02-27 03:15:02

标签: javascript recursion

我正在尝试更好地理解递归,因此尝试使用常见的“Fizzbuzz”创建一个带数字的数组。问题。我试图通过实现一个只有一个输入的纯递归函数来做到这一点,但我无法让我的答案以正确的顺序出现。我也很想知道是否有办法编写一个纯递归函数,在这种情况下使用push而不是concat。任何帮助表示赞赏!我能够打印出所需的输出,但是按相反的顺序进行。以下是我到目前为止:

 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));
  }
};

4 个答案:

答案 0 :(得分: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));




它可能看起来很难看,但它解决了你的问题,代码变化很小(有时,这是一个关键要求)。

另一种解决方案是将fizzBuzzRecursiveresults联系起来。请注意,为了使其工作,您需要为[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));




第三种解决方案是更改递归函数,使其以相反的顺序迭代。你可以自己尝试一下:)

答案 1 :(得分: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));
}

答案 2 :(得分:0)

第一种方法:将数组作为参数传递



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));
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这是另一种未提及的方式:

var fizzBuzz = function(n) {
  if (n < 1) return [];
  
  if (n % 3 === 0 && n % 5 === 0) {
    return fizzBuzz(n - 1).concat(['FizzBuzz']);
  } else if (n % 3 === 0) {
    return fizzBuzz(n - 1).concat(['Fizz']);
  } else if (n % 5 === 0) {
    return fizzBuzz(n - 1).concat(['Buzz']);
  } else {
    return fizzBuzz(n - 1).concat([`${n}`]);
  }
};