我正在尝试编写一个程序,该程序将按数字总和对 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;
}
答案 0 :(得分:2)
有两种基本方法:
创建一个返回整数总和的函数,比如 sum(int a)
,然后在比较时调用它,这样 tab[i] > tab [j]
就变成了 sum(tab[i]) > sum (tab[j])
将总和存储到不同的数组中,与新数组进行比较,并在交换时交换原始数组和新数组
如果数组很小并且不占用额外内存,第一个解决方案就足够了,而第二个解决方案不需要重复计算总和。 map
也可以使用缓存方法,但只有在数组中有足够多的相同数字时才值得。
答案 1 :(得分:1)
由于您的数字是非负数且小于 1000,您可以对数字本身的数字总和进行编码。所以,这个公式是正确的:encoded_number = original_number + 1000 * sum_of_the_digits
。 encoded_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;
}