Как сортировать целочисленные цифры в порядке возрастания без строк или массивов?

Я пытаюсь отсортировать цифры целого числа любой длины в порядке возрастания без использования строк, массивов или рекурсии.

пример:

Input: 451467
Output: 144567

Я уже выяснил, как получить каждую цифру целого числа с делением по модулю:

int number = 4214;

while (number > 0) {
    IO.println(number % 10);
    number = number / 10;
}

но я не знаю, как упорядочить цифры без массива.

не беспокойтесь о IO класс, это пользовательский класс наш профессор дал нам.

8 ответов


есть очень простой алгоритм, который использует только целые числа:

int number = 4214173;
int sorted = 0;
int digits = 10;
int sortedDigits = 1;
boolean first = true;

while (number > 0) {
    int digit = number % 10;

    if (!first) {

        int tmp = sorted;
        int toDivide = 1;
        for (int i = 0; i < sortedDigits; i++) {
            int tmpDigit = tmp % 10;
            if (digit >= tmpDigit) {
                sorted = sorted/toDivide*toDivide*10 + digit*toDivide + sorted % toDivide;
                break;
            } else if (i == sortedDigits-1) {
                sorted = digit * digits + sorted;
            }
            tmp /= 10;
            toDivide *= 10;
        }
        digits *= 10;
        sortedDigits += 1;
    } else {
        sorted = digit;
    }

    first = false;
    number = number / 10;
}
System.out.println(sorted);

выводит 1123447. Идея проста:

  1. вы берете текущую цифру числа, которое хотите отсортировать (назовем ее N)
  2. вы проходите через все цифры в уже отсортированном номере (назовем его S)
  3. если текущая цифра в S меньше текущей цифры в N, вы просто вставляете цифру в текущую позицию в S. В противном случае вы просто перейдите к следующей цифре в с.

эта версия алгоритма может сортировать в обоих ASC в порядках desc, вам просто нужно изменить условие.

кроме того, я предлагаю вам взглянуть на так называемый Radix Sort, решение здесь берет некоторые идеи из сортировки radix, и я думаю, что сортировка radix является общим случаем для этого решения.


это 4 строки, основанные на for вариант цикла вашего цикла while с небольшим Java 8 spice:

int number = 4214;

List<Integer> numbers = new LinkedList<>(); // a LinkedList is not backed by an array
for (int i = number; i > 0; i /= 10)
    numbers.add(i % 10);
numbers.stream().sorted().forEach(System.out::println); // or for you forEach(IO::println)

Я предполагаю, что вам разрешено использовать хэширование.

public static void sortDigits(int x) {
    Map<Integer, Integer> digitCounts = new HashMap<>();

    while (x > 0) {
        int digit = x % 10;
        Integer currentCount = digitCounts.get(digit);
        if (currentCount == null) {
            currentCount = 0;
        }
        digitCounts.put(x % 10, currentCount + 1);
        x = x / 10;
    }

    for (int i = 0; i < 10; i++) {
        Integer count = digitCounts.get(i);
        if (count == null) {
            continue;
        }
        for (int j = 0; j < digitCounts.get(i); j++) {
            System.out.print(i);
        }
    }
}

Как сортировать число без использования массива, строки или api сортировки? Ну, вы можете отсортировать число с помощью следующих простых шагов (если слишком много читать, то см. Вывод отладки ниже, чтобы получить представление о том, как выполняется сортировка):

  1. получить последнюю цифру числа, используя (цифра = число % 10)
  2. разделить число, чтобы последняя цифра исчезла (число /= 10)
  3. цикл через цифры номера (который не имеет цифры) и проверить, если цифра самый маленький
  4. если новая меньшая цифра найдена, замените цифру = наименьшая цифра и продолжайте искать до конца
  5. в конце цикла вы нашли наименьшую цифру, сохраните ее (store = (store * 10) + digit
  6. теперь, когда вы знаете, что это наименьшая цифра, удалите эту цифру из числа и продолжайте применять вышеуказанные шаги к оставшемуся числу, и каждый раз, когда меньшая цифра найдена, добавьте ее в магазин и удалите цифру из числа (если цифра повторяется в номер, затем удалите их все и добавьте их в магазин)

Я предоставил код с двумя циклами while в основном методе и одной функции. Функция ничего не делает, но строит новое целое число, исключая цифру, которая передается, например, я передаю функцию 451567 и 1, и функция возвращает мне 45567 (в любом порядке, не имеет значения). Если эта функция передается 451567 и 5, то она находит как 5 цифр в номере, так и добавляет их в хранилище и возвращает номер без 5 цифр (это избежать дополнительной обработки).

отладка, чтобы узнать, как он сортирует целое число:

последняя цифра: 7 из числа: 451567
Subchunk является 45156
Subchunk является 4515
Subchunk составляет 451
Subchunk составляет 45
Subchunk составляет 4
Smalled цифра в 451567 составляет 1
Магазин : 1
Удалить 1 из 451567
Уменьшенное число: 76554
Последняя цифра: 4 из числа: 76554
Subchunk это 7655
Subchunk составляет 765
Subchunk составляет 76
Subchunk составляет 7
Smalled цифра в 76554 составляет 4
магазин : 14
Удалить 4 из 76554
Уменьшенное число: 5567
Последняя цифра: 7 из числа: 5567
Subchunk составляет 556
Subchunk составляет 55
Subchunk составляет 5
Smalled цифра в 5567 составляет 5
магазин : 145
Удалить 5 из 5567
найдена повторная минимальная цифра 5. Магазин является : 145
повторенная минимальная цифра 5 добавлена в магазин. Обновленный магазин: 1455

Уменьшенное число: 76
Последняя цифра: 6 из числа: 76
Subchunk составляет 7
Smalled цифра в 76 составляет 6
магазин : 14556
Удалить 6 из 76
Уменьшенное число: 7
Последняя цифра: 7 из числа: 7
Smalled цифра 7-это 7
магазин : 145567
Удалить 7 из 7
Сокращается число : 0
возрастающий порядок 451567 - 145567

пример кода выглядит следующим образом:

//stores our sorted number
     static int store = 0; 

     public static void main(String []args){
        int number = 451567; 
        int original = number; 

        while (number > 0) {
            //digit by digit - get last most digit
            int digit = number % 10;

            System.out.println("Last digit is : " + digit + " of number : " + number); 

            //get the whole number minus the last most digit 
            int temp = number / 10; 

            //loop through number minus the last digit to compare
            while(temp > 0) {
                System.out.println("Subchunk is " + temp); 
                //get the last digit of this sub-number
                int t = temp % 10; 

                //compare and find the lowest
                //for sorting descending change condition to t > digit
                if(t < digit)   
                    digit = t; 

                //divide the number and keep loop until the smallest is found
                temp = temp / 10;
            }
            System.out.println("Smalled digit in " + number  + " is " + digit); 

            //add the smallest digit to store 
            store = (store * 10) + digit; 

            System.out.println("Store is : " + store); 

            //we found the smallest digit, we will remove that from number and find the 
            //next smallest digit and keep doing this until we find all the smallest 
            //digit in sub chunks of number, and keep adding the smallest digits to 
            //store
            number = getReducedNumber(number, digit); 
        }
        System.out.println("Ascending order of " + original + " is " + store); 
     }


     /*
     * A simple method that constructs a new number, excluding the digit that was found
     * to b e smallest and added to the store. The new number gets returned so that 
     * smallest digit in the returned new number be found.
     */
     public static int getReducedNumber(int number, int digit) {
        System.out.println("Remove " + digit + " from " + number); 
        int newNumber = 0; 

        //flag to make sure we do not exclude repeated digits, in case there is 44
        boolean repeatFlag = false; 
        while(number > 0) {
            int t = number % 10; 
            //assume in loop one we found 1 as smallest, then we will not add one to the new number at all
            if(t != digit) {
                newNumber = (newNumber * 10) + t; 
            } else if(t == digit) {
                if(repeatFlag) {
                    System.out.println("Repeated min digit " + t + "found. Store is : " + store);
                    store = (store * 10) + t; 
                    System.out.println("Repeated min digit " + t + "added to store. Updated store is : " + store);
                    //we found another value that is equal to digit, add it straight to store, it is 
                    //guaranteed to be minimum
                } else {
                    //skip the digit because its added to the store, in main method, set flag so 
                    // if there is repeated digit then this method add them directly to store
                    repeatFlag = true; 
                }
            }
            number /= 10; 
        }
        System.out.println("Reduced number is : " + newNumber); 
        return newNumber; 
     }
}

мой алгоритм это:

int ascending(int a)
{
    int b = a;
    int i = 1;
    int length = (int)Math.log10(a) + 1;   // getting the number of digits
    for (int j = 0; j < length - 1; j++)
    {
        b = a;
        i = 1;
        while (b > 9)
        { 
            int s = b % 10;                // getting the last digit
            int r = (b % 100) / 10;        // getting the second last digit
            if (s < r)
            {
                a = a + s * i * 10 - s * i - r * i * 10 + r * i; // switching the digits
            }
            b = a;
            i = i * 10;
            b = b / i;                     // removing the last digit from the number
        }
    }
    return a;
}

добавление очень простого алгоритма, который не нуждается в каких-либо структурах данных или причудливой математике, как и другие.

int number = 65356;
for (int i = 0; i <= 9; i++) { // the possible elements are known, 0 to 9
    int tempNumber = number;
    while (tempNumber > 0) {
        int digit = tempNumber % 10;
        IO.print(digit);
        tempNumber = number / 10;
    }
}

словами:
1. Выведите 0 для каждого 0 в числе.
2. Распечатать 1 для каждого 1 числа.
...


вот простое решение :

    public class SortDigits
    {
        public static void main(String[] args)
        {
            sortDigits(3413657);
        }

        public static void sortDigits(int num)
        {
            System.out.println("Number  : " + num);
            String number = Integer.toString(num);
            int len = number.length(); // get length of the number
            int[] digits = new int[len];
            int i = 0;
            while (num != 0)
            {
                int digit = num % 10;
                digits[i++] = digit; // get all the digits
                num = num / 10;
            }
            System.out.println("Digit before sorting: ");
            for (int j : digits)
            {
                System.out.print(j + ",");
            }
            sort(digits);
            System.out.println("\nDigit After sorting: ");
            for (int j : digits)
            {
                System.out.print(j + ",");
            }
        }
        //simple bubble sort 
        public static void sort(int[] arr)
        {
            for (int i = 0; i < arr.length - 1; i++)
                for (int j = i + 1; j < arr.length; j++)
                {
                    if (arr[i] > arr[j])
                    {
                        int tmp = arr[j];
                        arr[j] = arr[i];
                        arr[i] = tmp;
                    }
                }
        }
    }

class SortDigits {
    public static void main(String[] args) {
        int inp=57437821;
        int len=Integer.toString(inp).length();
        int[] arr=new int[len];
        for(int i=0;i<len;i++)
        {
            arr[i]=inp%10;
            inp=inp/10;
        }
        Arrays.sort(arr);
        int num=0;
        for(int i=0;i<len;i++)
        {
            num=(num*10)+arr[i];
        }
        System.out.println(num);
    }    
}