简体   繁体   English

排序整数的数字

[英]Sorting digits of an integer

You are given an integer 51234 (say) we need to sort the digits of a number the output will be 12345 . 给你一个整数51234 (比方说)我们需要对一个数字的数字进行排序,输出将是12345

How to do it without using array ? 不使用数组怎么做?

You can use a loop and % 10 to extract each digit. 您可以使用循环和% 10来提取每个数字。 An outer loop from 0 to 9 could be used to test if the digit exists. 从0到9的外部循环可用于测试数字是否存在。 If it exists, print it. 如果存在,请将其打印出来。

In pseudo code: 在伪代码中:

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

Edit: This test in gcc shows that it handles zeros and repeated digits: 编辑: 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
// 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

General overview: 总体概述:

  • loop for i = 0 to 9 循环为i = 0到9
  • in each loop iteration, walk through the digits in the number (using another loop that does a "mod 10" operation to peel off the digits until the number reduces to zero) - if it matches the digit you're currently working on, print it 在每个循环迭代中,遍历数字中的数字(使用执行“mod 10”操作的另一个循环来剥离数字,直到数字减少到零) - 如果它与您当前正在处理的数字匹配,则打印它

The only potentially tricky bit might be properly handling zeros - you don't want too many, and you'll want to handle the edge case where the input is zero properly. 唯一可能很棘手的位可能是正确处理零 - 你不需要太多,并且你想要处理输入为零的边缘情况。

Actual implementation is left as an exercise... 实际实施留作练习......

Easy: 简单:

#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;
}

Compiling and running: 编译和运行:

$ 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

:-) :-)

Another solution, not using arrays, and pretty short on line-count: 另一个解决方案,不使用数组,并且在行数上相当短:

#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;
}

Yes, I am aware of the "correct" solution. 是的,我知道“正确”的解决方案。 But why would one not use arrays for this problem? 但为什么不使用数组来解决这个问题呢? As one of the commentators said, I wouldn't want to work for a company that wouldn't let me use arrays in C. 正如其中一位评论员所说,我不想为一家不让我在C中使用数组的公司工作。

您根本不需要编写程序,只需使用shell命令:

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

Divide by 10 given integer in loop. 在循环中除以10给定的整数。 Print the reminder in each iteration. 在每次迭代中打印提醒。

Or "sort" means what here? 或者“排序”意味着什么? For real sorting you will need two loops. 对于真正的排序,您将需要两个循环。 One of them will be from 0 to 9. Another one will be that was described early. 其中一个将是从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;
}

Sure arrays are out, but we've got a better container anyway: 确定阵列已经出局,但无论如何我们还有一个更好的容器:

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

Use multiset if your input includes numbers like 887 that should be printed as 788 如果您的输入包含应打印为788 887数字,请使用multiset

One could try something like an insertion sort. 人们可以尝试类似插入排序的东西。 Essentially create a new number from taking one digit of the old one at a time and putting it in the correct place.something like this. 基本上创建一个新的数字,从一次取一个旧数字并将其放在正确的位置。这样的事情。

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

Create a container interface over the int (something like vector), where operator references the i'th decimal digit. 在int上创建一个容器接口(类似于vector),其中operator引用第i个十进制数字。 You would have to define iterators and other things too. 您还必须定义迭代器和其他东西。 Then call std::sort on it. 然后在它上面调用std :: sort。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM