Сортировка цифр целого числа

Вам присваивается целое число 51234 (скажем), нам нужно отсортировать цифры номера, который будет выводиться 12345.

Как это сделать без использования массива?

Ответ 1

Вы можете использовать цикл и % 10 для извлечения каждой цифры. Внешний цикл от 0 до 9 может использоваться для проверки наличия цифры. Если он существует, распечатайте его.

В псевдокоде:

n = integer // 51234
FOR digit = 0 TO 9
  temp = n
  REPEAT
    IF temp % 10 = digit THEN PRINT digit
    temp /= 10
  UNTIL temp = 0

Изменить: Этот тест в gcc показывает, что он обрабатывает нули и повторяющиеся цифры:

$ cat sortdigits.c
#include <stdio.h>
main () {
 int n,digit,temp;
 n = 43042025;
 for (digit=0;digit<9;digit++)
   for (temp=n;temp>0;temp/=10)
     if (temp%10==digit) printf("%d",digit);
 printf("\n");
}
$ ./sortdigits
00223445

Ответ 2

// Bubblesort
long sortNum(long n) {
  while (true) {
    long a = n % 10, p = 9;
    bool s = false;
    for (long r = n / 10; r; r/= 10) {
      long b = r % 10;
      if (a < b) {
        n -= p * (b - a);
        s = true;
      } else a = b;
      p *= 10;
    }
    if (!s) return n;
  }
}

#include <iostream>

int main(int argc, char **argv) {
  if (argc > 1) {
    long n = strtol(argv[1], 0, 0);
    std::cout << "Unsorted: " << n << std::endl;
    n = sortNum(n);
    std::cout << "Sorted:   " << n << std::endl;
  }
  return 0;
}

$ g++ -Wall -Wextra bubble-int.cpp && ./a.exe 183974425
Unsorted: 183974425
Sorted:   123445789

Ответ 3

Общий обзор:

  • для я = от 0 до 9
  • в каждой итерации цикла, пройдите цифры в цифре (используя другой цикл, который выполняет операцию "mod 10", чтобы отключить цифры до тех пор, пока число не уменьшится до нуля) - если оно соответствует цифре, которую вы сейчас работаете on, распечатать его

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

Фактическая реализация остается в виде упражнения...

Ответ 4

Легко:

#include <stdio.h>
#include <stdlib.h>

static void pput(int n, int c)
{
    int i;
    for (i=0; i < n; ++i) putchar(c);
}

int main(int argc, char *argv[])
{
    int zeros = 0;
    int ones = 0;
    int twos = 0;
    int threes = 0;
    int fours = 0;
    int fives = 0;
    int sixes = 0;
    int sevens = 0;
    int eights = 0;
    int nines = 0;
    long num = 0;

    if (argc > 1) {
        char *eptr;
        num = strtol(argv[1], &eptr, 0);
        if (*eptr) {
            fprintf(stderr, "Invalid number: '%s', using 0.\n", argv[1]);
            num = 0;
        }
    }
    do {
        switch (num % 10) {
            case 0: ++zeros;
                    break;
            case 1: ++ones;
                    break;
            case 2: ++twos;
                    break;
            case 3: ++threes;
                    break;
            case 4: ++fours;
                    break;
            case 5: ++fives;
                    break;
            case 6: ++sixes;
                    break;
            case 7: ++sevens;
                    break;
            case 8: ++eights;
                    break;
            case 9: ++nines;
                    break;
            default:
                    break;
        }
    } while ((num /= 10));
    pput(zeros, '0');
    pput(ones, '1');
    pput(twos, '2');
    pput(threes, '3');
    pput(fours, '4');
    pput(fives, '5');
    pput(sixes, '6');
    pput(sevens, '7');
    pput(eights, '8');
    pput(nines, '9');
    putchar('\n');
    return 0;
}

Компиляция и запуск:

$ gcc -Wextra -Wall -ansi -pedantic -Wfloat-equal -Wundef -Wshadow \
  -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes \
  -Wswitch-default -Wswitch-enum -Wstrict-overflow=5 \
  -Wdeclaration-after-statement -Wwrite-strings -Wconversion \
  -Waggregate-return -Wunreachable-code a.c
$ ./a.out
0
$ ./a.out 54321
12345
$ ./a.out 9834346
3344689
$ ./a.out hello
Invalid number: 'hello', using 0.
0

: -)

Другое решение, не использующее массивы, и довольно короткое количество строк:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    long num = 0;
    int i;
    size_t *freq;

    if (argc > 1) {
        char *eptr;
        num = strtol(argv[1], &eptr, 0);
        if (*eptr || errno == ERANGE) {
            fprintf(stderr, "Invalid number: '%s', using 0.\n", argv[1]);
            num = 0;
        }
    }

    if ((freq = calloc(10, sizeof *freq)) == NULL) {
        perror("malloc failure");
        return EXIT_FAILURE;
    }

    do
        ++freq[num % 10];
    while ((num /= 10));

    for (i=0; i < 10; ++i) {
        size_t j;
        for (j=0; j < freq[i]; ++j)
            putchar(i + '0');
    }
    putchar('\n');
    free(freq);

    return EXIT_SUCCESS;
}

Да, я знаю о "правильном" решении. Но почему бы не использовать массивы для этой проблемы? Как сказал один из комментаторов, я бы не хотел работать в компании, которая не позволяла мне использовать массивы в C.

Ответ 5

Вам вообще не нужно писать программу, просто сделайте это с помощью команд оболочки:

echo "51234" | sed 's+\(.\)+\1\n+g' | sort | tr -d '\n'

Ответ 6

Разделить на 10 заданных целых чисел в цикле. Распечатайте напоминание на каждой итерации.

Или "сортировка" означает, что здесь? Для реальной сортировки вам понадобятся две петли. Один из них будет от 0 до 9. Еще один будет описан ранее.

int main()
{
    int x = 0;
    cin >> x;

    for ( int l = 0; l < 10; ++l )
    {
        int rem = x % 10;
        int tx = x / 10;
        while ( rem || tx )
        {
            if ( rem == l ) cout << rem;
            rem = tx % 10;
            tx = tx / 10;
        }
    }
    cout << endl;
}

Ответ 7

Уверенные массивы отсутствуют, но у нас есть лучший контейнер:

void foo(unsigned i) {
  std::set<char> digits;
  do {
    digits.insert(`0` + i % 10);
    i /= 10;
  while(i!=0);
}

Используйте multiset, если ваш ввод содержит цифры типа 887, которые должны быть напечатаны как 788

Ответ 8

Можно попробовать что-то вроде сортировки вставки. По существу, создайте новый номер, взяв одну цифру из старой за раз и положив ее в нужное место. Что-то вроде этого.

while(num!=0){

dig = num%10; // get the last digit 
if(newNum=0 ) newNum+=dig;
else{
    newNumTemp = 0; flag =1;i =1;
    while (newNum != 0){
    Newdig = newNum%10;
   if(flag){
      if (Newdig >= dig )
         {NewNumTemp = Newdig*(10^i)+ NewNumTemp; }
      else { flag=0; NewNumTemp = dig*(10^i) +NewNumTemp; i++;NewNumTemp = Newdig*   (10^i)+    NewNumTemp;}

     } // end of outer if 
     i++;
     newNum/=10;

   } // end of while
   newNum= newNumTemp;
}// end of else 

num/=10;

}// end of outer while

Ответ 9

Создайте контейнерный интерфейс над int (что-то вроде вектора), где оператор ссылается на десятичную цифру i-го. Вам придется определять итераторы и другие вещи. Затем вызовите std:: sort.;)