我被要求编写一个运行时间为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;
}
交换开关元件, 谁能告诉我该如何解决?
谢谢:)
答案 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;
}
}
}
答案 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;
}