英文:
I'm doing a task on code wars and it doesn't work
问题
I did a task on code wars 4 kuy (Next bigger number with the same digits) and it seems to me that the problem is not even in my code, but on the site. When you click on the test, the program works correctly, but when you click on attempt, it doesn't.
Here are the instructions:
创建一个函数,该函数接受一个正整数并返回通过重新排列其数字可以形成的下一个更大的数字。例如:
12 ==> 21
513 ==> 531
2017 ==> 2071
nextBigger(num: 12) // 返回 21
nextBigger(num: 513) // 返回 531
nextBigger(num: 2017) // 返回 2071
9 ==> -1
111 ==> -1
531 ==> -1
Here is my code:
public static long nextBiggerNumber(long n) {
int count = 1;
char tmp;
char[] array = Long.toString(n).toCharArray();
for (int i = 0; i < Long.toString(n).length() - 1; i++) {
if (array[array.length - (count + 1)] < array[array.length - count]) {
tmp = array[array.length - count];
array[array.length - count] = array[array.length - (count + 1)];
array[array.length - (count + 1)] = tmp;
break;
}
count++;
tmp = 0;
}
if (Long.parseLong(String.valueOf(array)) == n) return -1;
/********************************************************************************************************************************/
char[] second = new char[count];
String.valueOf(array).getChars(array.length - count , array.length, second, 0);
int N = 1;
for (int i = 0; i < second.length - 1; i++) {
for (int j = N; j < second.length; j++) {
if (second[i] > second[j]){
tmp = second[i];
second[i] = second[j];
second[j] = tmp;
}
}
N++;
}
String mainString = String.valueOf(array).substring(0,array.length - count) + String.valueOf(second);
long mainLong = Long.parseLong(mainString);
System.out.println(mainLong);
return mainLong;
}
Here is error:
测试结果:
KataTests
基本测试
随机测试
日志
335686145
预期:<335685146> 实际为:<335686145>
堆栈跟踪
完成时间 6 毫秒
更大的测试
日志
123456798
1234567908
59884848493558
预期:<59884848483559> 实际为:<59884848493558>
堆栈跟踪
完成时间 1 毫秒
完成时间 30 毫秒
Perhaps I don’t understand something, but it seems that the program on the site itself is not working correctly because in randomTests and biggerTests, a number is displayed that is not more than the first, but less.
英文:
I did a task on code wars 4 kuy (Next bigger number with the same digits) and it seems to me that the problem is not even in my code, but on the site. When you click on the test, the program works correctly, but when you click on attempt, it doesn't.
Here are the instructions:
Create a function that takes a positive integer and returns the next bigger number that can be formed by rearranging its digits. For example:
12 ==> 21
513 ==> 531
2017 ==> 2071
nextBigger(num: 12) // returns 21
nextBigger(num: 513) // returns 531
nextBigger(num: 2017) // returns 2071
9 ==> -1
111 ==> -1
531 ==> -1
Here is my code:
public static long nextBiggerNumber(long n) {
int count = 1;
char tmp;
char[] array = Long.toString(n).toCharArray();
for (int i = 0; i < Long.toString(n).length() - 1; i++) {
if (array[array.length - (count + 1)] < array[array.length - count]) {
tmp = array[array.length - count];
array[array.length - count] = array[array.length - (count + 1)];
array[array.length - (count + 1)] = tmp;
break;
}
count++;
tmp = 0;
}
if (Long.parseLong(String.valueOf(array)) == n) return -1;
/********************************************************************************************************************************/
char[] second = new char[count];
String.valueOf(array).getChars(array.length - count , array.length, second, 0);
int N = 1;
for (int i = 0; i < second.length - 1; i++) {
for (int j = N; j < second.length; j++) {
if (second[i] > second[j]){
tmp = second[i];
second[i] = second[j];
second[j] = tmp;
}
}
N++;
}
String mainString = String.valueOf(array).substring(0,array.length - count) + String.valueOf(second);
long mainLong = Long.parseLong(mainString);
System.out.println(mainLong);
return mainLong;
}
Here is error:
Test Results:
KataTests
basicTests
randomTests
Log
335686145
expected:<335685146> but was:<335686145>
Stack Trace
Completed in 6ms
biggerTests
Log
123456798
1234567908
59884848493558
expected:<59884848483559> but was:<59884848493558>
Stack Trace
Completed in 1ms
Completed in 30ms
Perhaps I don’t understand something, but it seems that the program on the site itself is not working correctly, because in randomTests and biggerTests a number is displayed that is not more than the first, but less.
答案1
得分: 0
问题
下一个数字,比如 abcdef,会变成类似 abcefd,有一个固定的前缀。
应该注意到,1357 是最小值(递增),7531 是最大值(递减)。
看一下
467468
467486 递减顺序 86 = 最大值,将 4 替换为下一个更大的 6 并增加 48
467648
467684
467846
467864
...
所以这个算法(类似于带进位的学校加法)是:
- 取末尾递减(最高)的数字,比如
[...][2]85441
中的85441
。 - 在
2
之后的下一个更大的数字是4
。 - 创建下一个数字
...[4][12458]
,其中的数字是递增的(最低)。
代码
我不会通过解决方案来破坏您的编码努力,但一般来说:
迭代必须从最高索引的递减开始。
public static long nextBiggerNumber(long num) {
char[] digits = Long.toString(num).toCharArray();
int n = digits.length;
int i = n - 1;
--i;
while (i >= 0 && digits[i] >= digits[i + 1]) {
--i;
}
if (i < 0) {
return -1L; // 没有更大的数字。
}
// 现在必须用下一个更大的数字替换 digits[i] [>i]。
// 注意 digits[i+1]..[n-1] 是递减的。
// 然后在 [i+1]..[n-1] 上的所有内容必须是递增的。
...
return Long.valueOf(new String(digits));
}
必须注意重复的数字(>=,下一个更大的数字)。
完整解决方案,根据请求:
public static long nextBiggerNumber(long num) {
char[] digits = Long.toString(num).toCharArray();
int n = digits.length;
int i = n - 1;
--i;
while (i >= 0 && digits[i] >= digits[i + 1]) {
--i;
}
if (i < 0) {
return -1L; // 没有更大的数字。
}
// 现在必须用下一个更大的数字替换 digits[i] [>i]。
// 注意 digits[i+1]..[n-1] 是递减的。
// 然后在 [i+1]..[n-1] 上的所有内容必须是递增的。
// 用更大的数字交换中间数字。
char middle = digits[i];
for (int j = n - 1; j > i; --j) { // 从递减的右子数组中开始找最小的。
if (digits[j] > middle) {
digits[i] = digits[j];
digits[j] = middle;
// 右子数组仍然是递减的。
break;
}
}
// 反转右子数组以获得最低值(递增子数组)。
for (int k = i + 1, j = n - 1; k < j; ++k, --j) {
char digit = digits[k];
digits[k] = digits[j];
digits[j] = digit;
}
return Long.valueOf(new String(digits));
}
为了测试这个函数,最好编写一个单元测试(可以检查下一个更大的数字是否确实更大)。以下是一个示例 main
函数。
public static void main(String[] args) {
long[] nums = {24354L, 3832L};
for (long num : nums) {
System.out.printf("* %d%n", num);
long numi = num;
do {
numi = nextBiggerNumber(numi);
if (numi == -1L) {
break;
}
System.out.printf(" --> %d%n", numi);
} while (numi != -1L);
}
}
编译;对结果进行了简单的测试。
在解决这种问题时,应该充分“可视化” - 在纸上进行模拟计算。
ASCII 艺术
___
数字 | |___
| | |___ ___
___|...|...|...|...|.......
| a | | | | b |___
| | | | | | |___
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
^ ^
'------交换-----'
___
| |___
___| | |___
|...|...|...|...|___........
| b | | | | a |___
| | | | | | |___
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
[ ]
'------反转------'
___
下一个数字 ___| |
___ ___| | |
| |....... ___|...|...|...|
| b | ___| a | | | |
| |___| | | | | |
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
- 在
a
后面的数组是递减的,这个子数组中没有更大的组合。 - 所以下一个更大的组合涉及从
a
开始的所有内容。 - 取
b
>a
并使其余部分递增将得到下一个数字。
英文:
The Problem
The next number of say abcdef would be something like abcefd, having a fixed prefix.
One should note that 1357 is the lowest value (increasing) and 7531 is the highest value (decreasing).
Look at
467468
467486 decreasing order 86 = largest, replace 4 with next higher 6 and inc 48
467648
467684
467846
467864
...
So the algorithm is (reminiscent of school addition with carry):
- Take the digits at the end that are decreasing (highest), say
85441
in[...][2]85441
. - The next higher digit after
2
is4
- Create the next number
...[4][12458]
with increasing digits (lowest).
The code
I will not spoil your coding efforts by a solution, but in general:
Iteration has to start at the highest index decreasing.
public static long nextBiggerNumber(long num) {
char[] digits = Long.toString(num).toCharArray();
int n = digits.length;
int i = n - 1;
--i;
while (i >= 0 && digits[i] >= digits[i + 1]) {
--i;
}
if (i < 0) {
return -1L; // No higher number.
}
// Now digits[i] must be replaced with next higher digit [>i].
// Mind that digits[i+1]..[n-1] are decreasing.
// And then at [i+1]..[n-1] everything must be increasing.
...
return Long.valueOf(new String(digits));
}
One must take care of repeating digits (>=, next higher digit).
Full solution, on request:
public static long nextBiggerNumber(long num) {
char[] digits = Long.toString(num).toCharArray();
int n = digits.length;
int i = n - 1;
--i;
while (i >= 0 && digits[i] >= digits[i + 1]) {
--i;
}
if (i < 0) {
return -1L; // No higher number.
}
// Now digits[i] must be replaced with next higher digit [>i].
// Mind that digits[i+1]..[n-1] are decreasing.
// And then at [i+1]..[n-1] everything must be increasing.
// Swap middle digit with a higher one.
char middle = digits[i];
for (int j = n - 1; j > i; --j) { // start with smalles in decreasing right subarray.
if (digits[j] > middle) {
digits[i] = digits[j];
digits[j] = middle;
// Right subarray still is decreasing.
break;
}
}
// Reverse right to lowest value (increasing subarray).
for (int k = i + 1, j = n - 1; k < j; ++k, --j) {
char digit = digits[k];
digits[k] = digits[j];
digits[j] = digit;
}
return Long.valueOf(new String(digits));
}
To test this a unit test would be ideal (could check that the next bigger number is indeed bigger), here a main.
public static void main(String[] args) {
long[] nums = {24354L, 3832L };
for (long num : nums) {
System.out.printf("* %d%n", num);
long numi = num;
do {
numi = nextBiggerNumber(numi);
if (numi == -1L) {
break;
}
System.out.printf(" --> %d%n", numi);
} while (numi != -1L);
}
}
Compiles; tested the results just perfunctory.
Such problems one should sufficiently "visualize" - play computer on paper.
ASCII Art
___
Number | |___
| | |___ ___
___|...|...|...|...|.......
| a | | | | b |___
| | | | | | |___
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
^ ^
'------swap-----'
___
| |___
___| | |___
|...|...|...|...|___........
| b | | | | a |___
| | | | | | |___
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
[ ]
'------reverse------'
___
Next Number ___| |
___ ___| | |
| |....... ___|...|...|...|
| b | ___| a | | | |
| |___| | | | | |
... | | | | | | | |
_____________|___|___|___|___|___|___|___|
- After
a
the array is decreasing there is no higher combination in that subarray. - So the next higher combination involves all from and including
a
. - Taking
b
>a
and the rest increasing will give the next number.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论