Я пытался написать код, который принимает целое число от 1 до 1_000_000 и возвращает наименьшее целое число с теми же цифрами, а если оно не существует, печатает 0.
Например
ввод: 156
вывод 165
ввод 330
выход 0
ввод 27711
вывод 71127
Моя проблема в том, что мой код ниже не возвращает правильный вывод для других входов.
Например, на входе 4231 на выходе должно быть 4312.
У меня возникли проблемы с поиском лучшего алгоритма, который возвращает правильный вывод для каждого ввода.
спасибо заранее
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String x = sc.nextLine();
char[] chars = new char[x.length()];
char[] oldChars = new char[x.length()];
char temp;
for (int i = 0; i < x.length(); i++) {
chars[i] = x.charAt(i);
oldChars[i] = chars[i];
}
if (x.length() > 3){
for (int j = 0; j < x.length(); j++) {
if (chars[0] < chars[j]) {
temp = chars[0];
chars[0] = chars[j];
chars[j] = temp;
break;
}
}
for (int j = 1; j <= x.length() ; j++) {
for (int i = 1; i < x.length() - 1; i++) {
if (chars[i] > chars[i+1]){
temp = chars[i];
chars[i] = chars[i+1];
chars[i+1] = temp;
}
}
}
for (int i = 0; i < x.length(); i++) {
System.out.print(chars[i]);
}
}
else if (x.length() == 1)
System.out.println(0);
else {
temp = chars[x.length()-2];
chars[x.length()-2] = chars[x.length()-1];
chars[x.length()-1] = temp;
if (chars[x.length()-2] > oldChars[x.length()-2])
for (int i = 0; i < x.length(); i++) {
System.out.print(chars[i]);
}
else
System.out.println(0);
}
sc.close();
}
}
Наименьшее целое число больше 156 равно 157. В вашем вопросе есть условия, о которых вы нам не сообщаете. Вам нужно отредактировать свой вопрос.
@DaveNewton Да, я имею в виду те же цифры! Я отредактировал вопрос.
Лучшее описание: for input N, find the smallest integer between N and 1,000,000 using the same digits in N
Не самое эффективное решение, но вы можете создать цикл for от N + 1 до 1_000_000 и проверить, содержит ли каждый индекс те же цифры, что и ввод, в другом порядке. Разорвите петлю на первом совпадении.




Если вы можете использовать коллекции apache commons4, а производительность не имеет значения, вы можете использовать что-то вроде этого:
package test;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.stream.Collectors;
public class NextNumberCalculator {
public int calculateNearest(int input) {
List<Character> inputChars = String.valueOf(input).chars()
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
return CollectionUtils.permutations(inputChars)
.stream()
.mapToInt(chars -> Integer.parseInt(StringUtils.join(chars, "")))
.filter(permutation -> permutation > input)
.min()
.orElse(0);
}
}
Вот некоторые модульные тесты:
package test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class NextNumberCalculatorTest {
private NextNumberCalculator calculator;
@BeforeEach
void setUp() {
calculator = new NextNumberCalculator();
}
@Test
void calculateNearest() {
Assertions.assertEquals(165, calculator.calculateNearest(156));
Assertions.assertEquals(0, calculator.calculateNearest(330));
Assertions.assertEquals(71127, calculator.calculateNearest(27711));
Assertions.assertEquals(414, calculator.calculateNearest(144));
}
}
Попробуйте это, пожалуйста
int muldigits(int n){
int result = 0;
String [] strings = String.valueOf(Math.abs(n)).split("(?!^)");
List<Integer> intsList = new ArrayList<>();
for (String string : strings) {
intsList.add(Integer.parseInt(string));
}
if (n<0){
Collections.sort(intsList);
String temp = Arrays.toString(intsList.toArray()).replace(", ", "");
System.out.println(temp);
result = - Integer.parseInt(temp.substring(1, temp.length()-1));
}else{
Collections.sort(intsList, Collections.reverseOrder());
String temp = Arrays.toString(intsList.toArray()).replace(", ", "");
result = Integer.parseInt(temp.substring(1, temp.length()-1));
}
return result;
}
Спасибо, что поделились своим ответом. Я пробовал этот код, но он не возвращает правильный ответ для разных входных данных. Чтобы поблагодарить вас за вашу доброту в помощи мне, я даю вам голос. Tnx снова.
Спасибо. Не могли бы вы дать мне различные входные данные, где этот код терпит неудачу?
Вы можете проверить это самостоятельно с различными входными данными. Ваш код просто переворачивает число, например, для ввода 156 ваш код возвращает 651, но правильный вывод 165. Или для ввода 330 ваш код должен возвращать 0, но он возвращает 330 и т. д. Дело в том, что нам нужно наименьшее целое число больше, чем Н.
Вот один подход.
N значащих цифр. N начинается с 2. Сохрани копию.N цифр.TreeMap<String>N цифр, вернуть новое значение
с новым окончанием, присоединенным к оригиналу.N на единицу и повторите процесс.public class NextLargestInteger {
public static void main(String[] args) {
Сгенерируйте 10 случайных чисел.
Random r = new Random();
for (int i = 0; i < 10; i++) {
int val = r.nextInt(Integer.MAX_VALUE);
System.out.printf("%-12s %-12s%n",val,nextHighest(Integer.toString(val)));
}
Печатает что-то вроде
1446553155 1446553[515]
1801279982 18012[82799]
1894877459 18948774[95]
805018669 8050186[96]
521703779 5217037[97]
1926164416 19261644[61]
1236907656 12369076[65]
1326860288 1326860[828]
1049149602 10491496[20]
1516995584 1516995[845]
В скобках справа показано, какие окончания были переставлены, чтобы получить минимум
Основной метод.
public static String nextHighest(String e) {
char[] digits = e.toCharArray();
// start two digits from the end
int i = digits.length - 2;
// tree set to store the permuted strings
NavigableSet<String> set = new TreeSet<>();
for (; i >= 0; i--) {
// the last N digits
char[] shortList =
Arrays.copyOfRange(digits, i, digits.length);
// save a copy of the original N digit ending
String originalTail = new String(shortList);
permute(shortList, digits.length - i, set);
// get the next higher ending from the set
String minTail = set.higher(originalTail);
// if it exists, return the value.
if (minTail != null) {
String head =
new String(Arrays.copyOfRange(digits, 0, i));
return String.format("%s[%s]", head, minTail);
}
// clear the set and try a larger ending.
set.clear();
}
// no success, return the original value.
return e;
}
Служебный метод для перестановки массива символов
public static void permute(char[] elements, int length,
Set<String> vals) {
if (length == 1) {
vals.add(new String(elements));
} else {
for (int i = 0; i < length; i++) {
permute(elements, length - 1, vals);
if (length % 2 == 1) {
swap(elements, 1, length - 1);
} else {
swap(elements, i, length - 1);
}
}
}
}
Служебный метод для замены элементов массива.
public static void swap(char[] list, int i, int j) {
char temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
Спасибо за полное и точное объяснение. Вы действительно помогли.
n + 1кажется достаточным. Возможно, вы неправильно описываете свою проблему — вы имеете в виду «наименьшее целое число, которое можно составить из цифр вn»?