程序按余数3排序数组

时间:2019-02-15 13:25:04

标签: c arrays

我被要求编写一个运行时间为n的有效函数,该函数将数组除以3的余数,然后程序将余数除以3的元素为0,然后将余数为1的元素再乘以2 例如数组{7,16,3,28,12,31,14,12} 将以这种方式排序{12,3,12,28,16,31,7,14} 所以我尝试编写一个有效的函数,但是它不能涵盖所有情况,并且不适用于所有数组

    int arr[] = { 7,16,3,28,12,31,14,12 };
    int rem0 = 0, rem1 = 1, rem2 = 2;

    for (int i = 0; i < 8; i++) {
        if (arr[i] % 3 == 0)
            rem0++;

        if (arr[i] % 3 == 1)
            rem1++;

        if (arr[i] % 3 == 2)
            rem2++;
    }

    int k = rem0, p = 0, m = 0 = 0;

    for (int i = 0; i < 8; i++) {
        while (rem0-k){
            swap(&arr[i], &arr[rem0 - k]);
            k--;
        }
        if (arr[i] % 3 == 1 && rem0+m<7) {
            swap(&arr[i], &arr[rem0 + m]);
            m++;
        }
        if (arr[i] % 3 == 1 && rem0 + rem1 + p<7) {
            swap(&arr[i], &arr[rem0+rem1 + p]);
            p++;
        }
    }

    for (int l = 0;l <8;l++) {
        printf("%d\n", arr[l]);
    }
}

void swap(int *a, int *b) 
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

交换开关元件, 谁能告诉我该如何解决?

谢谢:)

5 个答案:

答案 0 :(得分:2)

由于您希望函数在O(n)时间内运行,因此无法对数组进行完全排序。您需要做的就是将所有元素放入3个存储桶中。 以下算法分两个阶段运行。

//First we count the number of elements in each bucket 
int count[3] ={0, 0, 0};
for (int i = 0; i < NUM_ELEMENTS; i++) {
    count[arr[i]%3]++;
}

现在我们有了元素数量,我们可以计算每个存储桶的偏移量并创建并输出数组

int output[NUM_ELEMENTS]; // In place bucketing can also be done using swaps
count[2] = count[0] + count[1];
count[1] = count[0];
count[0] = 0;


for (int i = 0; i < NUM_ELEMENTS; i++) {
    output[count[arr[i]%3]] = arr[i];
    count[arr[i]%3]++;
}

// Finally print the array

for (int i = 0; i < NUM_ELEMENTS; i++) {
    printf("%d", output[i]);
}

Ideone上的演示

答案 1 :(得分:1)

这里是您正在寻找的使用相同数组的解决方案:

#include <stdio.h>

#define REMINDER 3

void swap(int *a, int *b) 
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}    

int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,0};
    int arr_size = sizeof(arr)/sizeof(arr[0]);

    int idx=0;
    for (int r=0; r<REMINDER; r++) {
        for (int i=0; i<arr_size; i++) {
            if (arr[i]%REMINDER==r) {
                swap(&arr[idx++], &arr[i]);
            }
        }
    }

    for (int i=0; i<arr_size; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}

这是另一种解决方案,通过使用其他位置存储结果更简单:

#include <stdio.h>

#define REMINDER 3
#define ARR_SIZE 10

int main()
{
    int arr[ARR_SIZE] = {1,2,3,4,5,6,7,8,9,0};
    int arr_sorted[ARR_SIZE];

    int idx=0;
    for (int r=0; r<REMINDER; r++) {
        for (int i=0; i<ARR_SIZE; i++) {
            if (arr[i]%REMINDER==r) {
                arr_sorted[idx++]=arr[i];
            }
        }
    }

    for (int i=0; i<ARR_SIZE; i++) {
        printf("%d ", arr_sorted[i]);
    }

    return 0;
}

答案 2 :(得分:1)

这是一个1-pass就地Dutch national flag algorithm实现(感谢@Virgile指出了算法)

void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

// Dutch National Flag (see xlinux.nist.gov/dads/HTML/DutchNationalFlag.html)
void sort3dnf(int *a, size_t n) {
    int *bot = a;
    int *mid = a;
    int *top = a + n - 1;
    while (mid <= top) {
        switch (*mid % 3) {
            default: swap(bot++, mid++); break;
            case 1: mid++; break;
            case 2: swap(mid, top--); break;
        }
    }
}

请参见ideone.com/6QXXCN

答案 3 :(得分:0)

嘿,谢谢你的建议 可悲的是我们要求编写代码 没有添加任何数组 如果您能帮助我,我将非常高兴 解决问题 谢谢:)

答案 4 :(得分:0)

  

嘿,谢谢您的建议,可惜我们请求编写代码而不添加任何数组,如果您能帮助我解决问题,我将非常高兴:)

这是不添加任何额外数组的答案:

#include <stdio.h>
#define REMINDER 3

void swap(int *a, int *b) 
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}    

int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,0};
    int arr_size = sizeof(arr)/sizeof(arr[0]);

    int idx=0;
    for (int r=0; r<REMINDER; r++) {
        for (int i=0; i<arr_size; i++) {
            if (arr[i]%REMINDER==r) {
                swap(&arr[idx++], &arr[i]);
            }
        }
    }

    for (int i=0; i<arr_size; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}