我试图在codewars网站上解决这个问题。作为初学者,我遇到了实现各种编程技术的困难,缺乏基本的编程概念,如范围,提升等。无论如何,我决心解决这个问题。
说明说:
写一个函数,持久性,它接受一个正参数num并返回它的乘法持久性,这是你必须乘以num中的数字直到达到一位数的次数。
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
现在我只想得到这个结果3*9 = 27, 2*7 = 14, 1*4=4
但是我被卡住了。我知道我错过了什么,请给我一些宝贵的建议!
我的代码如下所示:
function persistence(num) {
var total = 1;
var step = 0;
var number = multiple(num);
while (step < 3) {
for (var i = 0; i < number.length; i++) {
total *= splitNumbers[i];
}
multiple(number);
step += 1;
}
}
function multiple(num) {
var splitNumbers = num.toString().split('');
var a = splitNumbers[0];
var b = splitNumbers[1];
return a * b;
}
persistence(39);
答案 0 :(得分:2)
奇怪的是,在第二个函数中你计算了一个产品(忽略了除前两个之外的所有数字),然后在main函数中你把它当作一个字符串(它不是'),然后开始再次乘以这些数字。这不是递归的原则:你应该只执行一次操作,然后进行递归调用。
这是一个解决方案:
function persistence(num) {
var digits = getDigits(num);
if (digits.length === 1) return 0; // number has only 1 digit, so we're done
var product = getProduct(digits);
return 1 + persistence(product); // we performed one transformation, now recurse
}
function getDigits(num) {
return num.toString().split('').map(Number); // convert chars to numbers
}
function getProduct(nums) {
return nums.reduce(function (a, b) { // nice way to get 1 result from array
return a * b;
}, 1);
}
console.log(persistence(39));
&#13;
答案 1 :(得分:1)
从单个函数开始,如果满足条件,则返回结果(只剩下一个数字)。如果没有,则返回下一次迭代的结果,传入要跟踪的状态(当前计数)。也许是这样的:
function persistence(num, opt_count) {
num = parseInt(num, 10); // Assume we're dealing with only ints.
var count = opt_count || 0; // Count is optional, so make sure we init.
if (num > 9) {
var digits = String(num).split(''); // Split our number as string.
num = digits.shift();
do {
num *= digits.shift(); // Note, multiplication will cast back automatically.
} while(digits.length);
count++; // Increment our count
}
if (num < 10) return count; // Return our count if we're under 10.
return persistence(num, count); // Recurse with our current state.
}
console.log('39: ' + persistence(39)); // 3
console.log('999: ' + persistence(999)); // 4
console.log('4: ' + persistence(4)); // 0
&#13;
答案 2 :(得分:1)
您的代码中存在一些问题:
function persistence(num) {
var total = 1;
var step = 0;
// This will return a number
var number = multiple(num);
while (step < 3) {
// Here number is a number, which doesn't have a length property so
// the loop never runs. However, once you fix that...
for (var i = 0; i < number.length; i++) {
// splitNumbers is in the multiple function, you can't access it
// from this function
total *= splitNumbers[i];
}
multiple(number);
step += 1;
}
// The function doesn't have a return statement, so even if it works,
// it returns undefined
}
function multiple(num) {
var splitNumbers = num.toString().split('');
var a = splitNumbers[0];
var b = splitNumbers[1];
return a * b;
}
console.log(persistence(39));
所以修复你的代码:
function persistence(num) {
var total = 1;
var step = 0;
var number = multiple(num);
// Make splitNumbers available locally
var splitNumbers = String(number).split('');
while (step < 3) {
// Use the length of splitNumbers, not number
for (var i = 0; i < splitNumbers.length; i++) {
total *= splitNumbers[i];
}
multiple(number);
step += 1;
}
// Return the accumulated step count
return step;
}
function multiple(num) {
var splitNumbers = num.toString().split('');
var a = splitNumbers[0];
var b = splitNumbers[1];
return a * b;
}
console.log(persistence(39));
但是这不是使用递归,你使用顺序编程,它比递归运行得更快(虽然不一定明显),但通常是更多的代码。
其他答案显示了一些很好的替代解决方案,这里有一个使用最近的功能(和递归):
function persistence(num, steps = 0) {
if (num > 9) steps++;
var total = (num || 0).toString().split('').reduce((a, b) => a * b);
return total > 9? steps += persistence(total) : steps;
}
[39, 999, 4].forEach(function(num) {
console.log(num + ' : ' + persistence(num));
});