Учитывая целое число N. Какое наименьшее целое число больше N в java

Я пытался написать код, который принимает целое число от 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();
}

}

n + 1 кажется достаточным. Возможно, вы неправильно описываете свою проблему — вы имеете в виду «наименьшее целое число, которое можно составить из цифр в n»?
Dave Newton 16.12.2020 20:47

Наименьшее целое число больше 156 равно 157. В вашем вопросе есть условия, о которых вы нам не сообщаете. Вам нужно отредактировать свой вопрос.

rossum 16.12.2020 20:48

@DaveNewton Да, я имею в виду те же цифры! Я отредактировал вопрос.

M.Barandov 16.12.2020 20:50

Лучшее описание: for input N, find the smallest integer between N and 1,000,000 using the same digits in N

hfontanez 16.12.2020 21:35

Не самое эффективное решение, но вы можете создать цикл for от N + 1 до 1_000_000 и проверить, содержит ли каждый индекс те же цифры, что и ввод, в другом порядке. Разорвите петлю на первом совпадении.

Gilbert Le Blanc 17.12.2020 00:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
5 245
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если вы можете использовать коллекции 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 снова.

M.Barandov 17.12.2020 11:54

Спасибо. Не могли бы вы дать мне различные входные данные, где этот код терпит неудачу?

Mamas Mavoungou Gael 17.12.2020 16:16

Вы можете проверить это самостоятельно с различными входными данными. Ваш код просто переворачивает число, например, для ввода 156 ваш код возвращает 651, но правильный вывод 165. Или для ввода 330 ваш код должен возвращать 0, но он возвращает 330 и т. д. Дело в том, что нам нужно наименьшее целое число больше, чем Н.

M.Barandov 18.12.2020 18:14
Ответ принят как подходящий

Вот один подход.

  • Начиная с наименее 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;
    }
} 

Спасибо за полное и точное объяснение. Вы действительно помогли.

M.Barandov 17.12.2020 11:48

Другие вопросы по теме