Reputation: 21
I was requested to write an effecient function with running time n which sort array by the remainder of 3 the program puts the elements which the remainder from dividing in 3 is 0 afterwards the elements that the remainder is 1 and afterwards 2 for example the array {7, 16, 3, 28, 12, 31, 14, 12} will be sortes that way {12, 3, 12, 28, 16, 31, 7, 14} so I tries to write an efficient function but it have not cover all cases and does not works for all arrays
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;
}
swap switch elements, Can anyone tells me how can I fix that?
thanks:)
Upvotes: 2
Views: 657
Reputation: 1036
hey thanks for the advice sadly we had requested to write the code without any added array I will be very glad if you could help me to solve the issue thanks :)
Here is the answer without adding any extra array:
#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;
}
Upvotes: 0
Reputation: 11
hey thanks for the advice sadly we had requested to write the code without any added array I will be very glad if you could help me to solve the issue thanks :)
Upvotes: 0
Reputation: 108938
Here's a 1-pass in-place Dutch national flag algorithm implementation (thanks to @Virgile who pointed out the algorithm)
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;
}
}
}
Upvotes: 1
Reputation: 9203
Since you want your function to run in O(n) time, you cannot sort the array completely. All you need to do is put all the elements in 3 buckets. The following algorithm runs in 2 phases.
//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]++;
}
Now that we have the number of elements, we can calculate the offsets of each bucket and create and output array
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]);
}
Demo on Ideone
Upvotes: 3
Reputation: 1036
Here is the solution which you are looking for which uses the same array:
#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;
}
Here is a another solution which is just simpler by using other place to store the result:
#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;
}
Upvotes: 1