按数字总和对整数进行排序

时间:2021-03-01 05:17:05

标签: c sorting

我正在尝试编写一个程序,该程序将按数字总和对 20 个随机数的数组进行排序。

例如:

"5 > 11" because 5 > 1+1 (5 > 2). 

我设法对总和进行了排序,但是否可以返回原始数字或以其他方式进行排序?

#include <stdio.h>
void sortujTab(int tab[], int size){
    int sum,i;
    for(int i=0;i<size;i++)
    {
        while(tab[i]>0){//sum as added digits of an integer
            int p=tab[i]%10;
            sum=sum+p;
            tab[i]/=10;
        }

        tab[i]=sum;
        sum=0;
    }
    for(int i=0;i<size;i++)//print of unsorted sums
    {
        printf("%d,",tab[i]);
    }
    printf("\n");
    for(int i=0;i<size;i++)//sorting sums
        for(int j=i+1;j<=size;j++)

        {
            if(tab[i]>tab[j]){
                int temp=tab[j];
                tab[j]=tab[i];
                tab[i]=temp;

            }
        }
    for(int i=0;i<20;i++)//print of sorted sums
    {
        printf("%d,",tab[i]);
    }
}
int main()
{
    int tab[20];
    int size=sizeof(tab)/sizeof(*tab);
    for(int i=0;i<=20;i++)
    {
        tab[i]=rand()%1000;// assamble the value
    }
    for(int i=0;i<20;i++)
    {
        printf("%d,",tab[i]);//print unsorted
    }
    printf("\n");

    sortujTab(tab,size);

    return 0;
}

3 个答案:

答案 0 :(得分:2)

有两种基本方法:

  1. 创建一个返回整数总和的函数,比如 sum(int a),然后在比较时调用它,这样 tab[i] > tab [j] 就变成了 sum(tab[i]) > sum (tab[j])

  2. 将总和存储到不同的数组中,与新数组进行比较,并在交换时交换原始数组和新数组

如果数组很小并且不占用额外内存,第一个解决方案就足够了,而第二个解决方案不需要重复计算总和。 map 也可以使用缓存方法,但只有在数组中有足够多的相同数字时才值得。

答案 1 :(得分:1)

由于您的数字是非负数且小于 1000,您可以对数字本身的数字总和进行编码。所以,这个公式是正确的:encoded_number = original_number + 1000 * sum_of_the_digitsencoded_number/1000 将解码数字的总和,而 encoded_number%1000 将解码原始数字。按照下面的修改代码。输出中括号括起来的数字是原始数字。我已尝试对您的代码进行最少的修改。

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

void sortujTab(int tab[], int size)
{
    for (int i = 0; i < size; i++) {
        int sum = 0, n = tab[i];
        while (n > 0) { //sum as added digits of an integer
            int p = n % 10;
            sum = sum + p;
            n /= 10;
        }    
        tab[i] += sum * 1000;
    }
    for (int i = 0; i < size; i++) { //print of unsorted sums
        printf("%d%c", tab[i] / 1000, i < size - 1 ? ',' : '\n');
    }

    for (int i = 0; i < size; i++) { //sorting sums
        for (int j = i + 1; j < size; j++) {
            if (tab[i] / 1000 > tab[j] / 1000) {
                int temp = tab[j];
                tab[j] = tab[i];
                tab[i] = temp;
             }
        }
    }

    for (int i = 0; i < size; i++) { //print of sorted sums
        printf("%d(%d)%c", tab[i] / 1000, tab[i] % 1000, i < size - 1 ? ',' : '\n');
    }
}

int main(void)
{
    int tab[20];
    int size = sizeof(tab) / sizeof(*tab);
    for (int i = 0; i < size; i++) {
        tab[i] = rand() % 1000; // assamble the value
    }
    for (int i = 0; i < size; i++) {
        printf("%d%c", tab[i], i < size - 1 ? ',' : '\n'); //print unsorted
    }

    sortujTab(tab, size);

    return 0;
}

如果数字范围不允许这样的编码,那么你可以声明一个包含两个整数元素的结构(一个是原始数字,一个是数字的总和),为{{1}分配一个数组} 这个结构体的元素,并使用数字和作为键对数组进行初始化和排序。

答案 2 :(得分:0)

您可以对索引数组进行排序,而不是对包含数据的数组进行排序。

#include <stdio.h>

//poor man's interpretation of sumofdigits() :-)
int sod(int n) {
    switch (n) {
        default: return 0;
        case 5: return 5;
        case 11: return 2;
        case 1000: return 1;
        case 9: return 9;
    }
}

void sortbyindex(int *data, int *ndx, int size) {
    //setup default indexes
    for (int k = 0; k < size; k++) ndx[k] = k;
    //sort the indexes
    for (int lo = 0; lo < size; lo++) {
        for (int hi = lo + 1; hi < size; hi++) {
            if (sod(data[ndx[lo]]) > sod(data[ndx[hi]])) {
                //swap indexes
                int tmp = ndx[lo];
                ndx[lo] = ndx[hi];
                ndx[hi] = tmp;
            }
        }
    }
}

int main(void) {
    int data[4] = {5, 11, 1000, 9};
    int ndx[sizeof data / sizeof *data];

    sortbyindex(data, ndx, 4);

    for (int k = 0; k < sizeof data / sizeof *data; k++) {
        printf("%d\n", data[ndx[k]]);
    }

    return 0;
}
相关问题