Javascript: пример использования рекурсивной функции для циклов и подстроки - не могу понять, где я ошибаюсь
В настоящее время я работаю над средней задачей кодербайта под названием "Шаг перестановки".
Цель состоит в том, чтобы получить пользовательский ввод num и вернуть следующее число, большее num, используя те же цифры. Так, например, если пользовательский ввод равен 123, тогда должно быть возвращено число 132. Если пользовательский ввод 12453, то должно быть возвращено 12534...
В любом случае, у меня есть верный модельный ответ, созданный кем-то (вероятно, гением, потому что этот материал довольно сложный), и я пытаюсь выяснить, как работает ответ, строка за строкой, разыгрывая пример (я продолжаю это просто и разыгрывает функцию с пользовательским вводом 123).
Ответ имеет 2 функции, но первая используемая функция - это то, что я сейчас пытаюсь решить...
Соответствующий код:
var PermutationStep1 = function(num) {
var num1 = num.toString();
var ar = [];
//return num1;
if (num1.length < 2) {
return num;
} else {
for(var i = 0; i < num1.length; i++) {
var num2 = num1[i];
var num3 = num1.substr(0,i) + num1.substr(i+1, num1.length -1);
var numAr = PermutationStep1(num3);
for(var j = 0; j < numAr.length; j++) {
ar.push(numAr[j] + num2);
}
}
ar.sort(function(a,b) {return a-b});
return ar;
}
}
Снова, я пытаюсь работать через эту функцию с введенным числом как 123 (число = 123).
Я уверен, что эта функция должна выводить массив с несколькими элементами, потому что 2-я функция просто сравнивает эти элементы массива с исходным пользовательским вводом (в нашем случае 123) и возвращает следующее наибольшее значение.
Поэтому в нашем случае нам, вероятно, следует получить массив с именем 'ar', возвращенный с множеством трехзначных значений. Но по какой-то причине я получаю массив из двухзначных значений. Кажется, я не могу изолировать свою ошибку и понять, куда я иду. Любая помощь, где, в частности, я иду не так (будь то рекурсия, использование substring-метода или объединение строк вместе, независимо от моей проблемы), будет принята с благодарностью...
Вот некоторые из моих работ на данный момент:
PS1(123) / num1 = 123
i = 0;
num2 = (num1[i]) = '1';
num3 = (num1.substr(0, 0) + num1.substr(1, 2)) = ('0' + '23') = '23'
PS1(23)
i = 0;
num2 = '2';
num3 = '3'
PS1(3) -> numAr = 3 (since num1 is less than 2 digits, which is the recursion base case?)
(So take 3 into the 2nd for loop)...
ar.push(numAr[j] + num2) = ar.push('3' + '1') = 31
ar = [31] at this point
And then I go through the initial for-loop a couple more times, where i = 1 and then i = 2, and I eventually get....
ar = [31, 32, 33]...
Но я думаю, что у меня должно быть что-то вроде ar = [131, 132, 133]? Я не уверен, где я иду не так, поэтому, пожалуйста, помогите. Поскольку ответ корректно выводится этой функцией, правильный ответ - 132.
Примечание: если вам нужна вторая часть ответа модели (т.е. вторая функция), вот она:
var arr = [];
function PermutationStep(num1) {
arr.push(PermutationStep1(num1));
var arrStr = arr.toString();
var arrStrSpl = arrStr.split(",");
//return arrStrSpl;
for(var p = 0; p < arrStrSpl.length; p++) {
if(arrStrSpl[p] > num1) {
return arrStrSpl[p];
}
}
return -1;
}
3 ответа
Я сожалею, что первая функция, которую я опубликовал, была под математической логической ошибкой, и я должен был поспешно подумать об этом снова, и теперь у меня есть следующая функция, которая определенно работает
function getNextNumber (num) { var numberStr=num.toString (), l=numberStr.length, i; var digits=new Array (), lighterDigits, digitAtWeight; var weight,lightWeight, lighterDigits_l, value=0; for (i=l-1;i>-1;i--) digits.push (parseInt(numberStr.charAt(i))); lighterDigits=new Array (); lighterDigits.push (цифры [0]); для (вес =1; вес <л; вес ++) {digitAtWeight = цифры [вес]; lighterDigits_l = lighterDigits.length; for (lightWeight = 0; lightWeightл; вес ++) значение +=Math.pow (10, вес)* цифры [вес]; возвращаемое значение; } } lighterDigits.push (digitAtWeight); } возврат NaN; }
Это решение, которое я нашел для решения проблемы без использования рекурсивной функции. Прошли все тесты на кодербайт. Я все еще новичок в этом, поэтому использование рекурсии - это не первое, что я ищу. надеюсь, что это может помочь кому-то еще в поисках решения.
function PermutationStep(num) {
var numArr = (num + '').split('').sort().reverse();
var numJoin = numArr.join('');
for (var i = (num + 1); i <= parseInt(numJoin); i++){
var aaa = (i + '').split('').sort().reverse();
if (aaa.join('') == numJoin){
return i;
}
}
return -1;
}
Хорошо, вот мое решение, я нашел его через 20 минут;)
// ---- num должен быть объектом Number, а не строкой функция getNextNumber (номер) { var numberStr=num.toString (), l=numberStr.length, i; var digits=new Array (), digitA, digitB; вар вес, легкий вес; var valueDifference, largeValue; для (i = 1-1;i>-1;i--) digits.push (parseInt(numberStr.charAt(i))); // 345 становится a0=5 a1=4 a2=3, и мы можем сказать, что num= a0*10^0+ a1*10^1+ a2*10^2, поэтому индекс становится десятичным весом для (вес = 1; вес <л; вес ++) { Digita = цифры [вес]; bigValue = new Array (); для (lightWeight = weight-1; lightWeight> -1;lightWeight--) { digitB= цифра [Lightweight]; если (digitB==digitA) продолжить; valueDifference=(digitA-digitB)*(-Math.pow(10,weight)+Math.pow (10,lightWeight)); if (valueDifference>0) bigValue.push(valueDifference); } if (bigValue.length>0) { biggerValue.sort(); return (большее значение [0]+ число); } } }