Counting sort not working as expected - c

I'm trying to implement counting sort as given the CLRS book. My code looks like this:
#include <stdio.h>
#include <stdlib.h>
void counting_sort(int numbers[], int k, int len)
{
int *temp = malloc(k*sizeof(int));
int *res = malloc(len*sizeof(int));
int i;
for(i = 0; i < k; i++)
{
temp[i] = 0;
}
for(i = 0; i < len; i++)
{
temp[numbers[i]]++;
}
for(i = 1; i < k; i++)
{
temp[i] += temp[i-1];
}
int j;
for(i = len-1; i >= 0; i--)
{
res[temp[numbers[i]]] = numbers[i];
temp[numbers[i]]--;
}
for(j = 0; j < len; j++)
printf("%d ", res[j]);
printf("\n");
free(temp);
free(res);
}
void main()
{
int numbers[] = {2, 5, 3, 0, 2, 3, 0, 3};
counting_sort(numbers, 6, 8);
}
But the output I get is: 0 0 0 2 2 3 3 3. The output is almost correct, I should get 0 0 2 2 3 3 3 5.
Any idea what is wrong? I have a feeling it's the last loop that's messing it up.

This line is wrong:
res[temp[numbers[i]]] = numbers[i];
changed it to this:
res[temp[numbers[i]]-1] = numbers[i];
It seem to work fine.

Related

Taking the transpose of a matrix in C with 1D arrays

I have a matrix that is represented by a one dimensional array,
example:
the matrix
0 1 2 3
4 5 6 7
8 9 10 11
the array
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
now give the dimensions of this matrix and the array I want to find the transpose, i.e.
0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11
I'm working in C and here is my code
#include <stdlib.h>
#include <stdio.h>
void transpose(int *array, int m, int n){
int new_array[12];
for (int i=0; i<m*n; i++) {
new_array[i] = ??;
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void print_array(int array[], int size){
for (int i=0; i<size; i++) {
printf("%d\n",array[i]);
}
}
int main(){
int array[12];
for (int i=0; i<12; i++) {
array[i]=i;
}
print_array(array,12);
transpose(array,3,4);
print_array(array,12);
return 0;
}
I've tried a dozen times and failed. Is there a simple way to do this that I have missed?
Use couple of for loops to make the code easier to follow.
void transpose(int *array, int m, int n){
int new_array[12];
for (int i = 0; i < m; ++i )
{
for (int j = 0; j < n; ++j )
{
// Index in the original matrix.
int index1 = i*n+j;
// Index in the transpose matrix.
int index2 = j*m+i;
new_array[index2] = array[index1];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void transpose(int *array, int m, int n){
int new_array[12];
int k = 0;
for(int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
new_array[k++] = array[j*n + i];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
Write the transpose in terms of a double loop over range [0..n) and [0..m) and calculate the indexes corresponding to the old position and the new position:
#include <stdio.h>
static void transpose(int *array, int m, int n)
{
int new_array[m * n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
int old_idx = i * n + j;
int new_idx = j * m + i;
new_array[new_idx] = array[old_idx];
}
}
for (int i = 0; i < m * n; i++)
{
array[i] = new_array[i];
}
}
static void print_array(int array[], int size)
{
for (int i = 0; i < size; i++)
{
printf(" %d", array[i]);
}
putchar('\n');
}
int main(void)
{
int array[12];
for (int i = 0; i < 12; i++)
{
array[i] = i;
}
print_array(array, 12);
transpose(array, 3, 4);
print_array(array, 12);
return 0;
}
The functions have to be pre-declared or made static to compile with my default compilation options. The transpose() function shown will work with any shape (size) of matrix (whereas the original won't work if the product of the dimensions is more than 12). I flattened the output from the array printer, too (though I'd probably make it print matrix shaped output if it were for 'production' use). I do assume that you have C99, or C11 with VLA support.
$ ./trans
0 1 2 3 4 5 6 7 8 9 10 11
0 4 8 1 5 9 2 6 10 3 7 11
$
I have changed:
for (int i = 0 ; i < m*n ; i++) {
new_array[i] = ??;
}
to:
int ctr = 0;
for (int i = 0 ; i <= m*n ; i++) {
if (ctr > m*n)
ctr -= m*n - 1;
new_array[i] = array[ctr];
ctr += n;
}
The logic is quite simple. Each row is n integers long and so the number below a num in the 2-D matrix form would be n+num
You can rewrite your transpose function as like this:
static void transpose(int *array, int m, int n)
{
int *temp=malloc(m*n*sizeof(int)); //need to create a temporary array.
memcpy(temp,array,m*n*sizeof(int));
int i, j;
for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
{
array[j*m+i]=temp[i*n+j];
}
}
free(temp);
}
You almost had it, I think this would do it...
void transpose(int *array, int m, int n){
int new_array[12];
int count;
count = 0;
for (int i=0; i < n; i++) {
for (int j=0; j < m; j += n) {
new_array[count++] = i + j;
}
}
for (int i=0; i < m * n; i++) {
array[i] = new_array[i];
}
}
This algorithm works for any number of rows an columns:
for (std::size_t i = 0; i < col; i++) {
for (std::size_t j = 0; j < row; j++) {
transpose[c++] = array[j * col + i];
}
}

C_(visual)_Debug Error_ Run-Time Check Failure #2 -S

I want to reverse numbers of array,
but I can't understand why it didn't run.
Thanks for explaining what does Debug Error_ Run-Time Check Failure #2 -S mean..
Thanks,
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5 };
int size, i, j;
int temp = 0;
size = sizeof(arr) / sizeof(arr[0]); //use this for changing size
printf("first_array :");
for (i = 0; i < size; i++)
{
printf("%d", arr[i]);
}
printf("\n");
for (i = 0; i <= (size / 2); i++)
{
j = size - i;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
printf("Riv_array :");
for (i = 0; i < size; i++)
{
printf("%d", arr[i]);
}
return 0;
}
Array index starts from 0 in C and your array has 5 elements so arr[4] is the last element but your code:
j = size - i;
arr[j];
when i=0 access to arr[5], this is your code error: Array index out of bound.
you should use j = size - i-1; to point to the last element of array, not j = size - i;
see this working sample (your sample code with some edit):
#include <stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int size, i, j;
int temp = 0;
size = sizeof(arr) / sizeof(arr[0]); //use this for changing size
printf("first_array :");
for (i = 0; i < size; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
for (i = 0; i <= (size / 2); i++)
{
j = size - i - 1;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
printf("Riv_array :");
for (i = 0; i < size; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
another way to reverse array using pointers:
#include <stdio.h>
void reverse(int* p, int count){
int temp;
int* q = p + count - 1; // point to the end
count /= 2;
while (count--) {
temp = *p;
*p++ = *q;
*q-- = temp;
}
}
void print_array(int *p, int count){
while (count--) printf("%d ", *p++);
printf("\n");
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int count = ((&arr)[1] - arr);
print_array(arr, count);
reverse(arr, count);
print_array(arr, count);
return 0;
}
output:
1 2 3 4 5
5 4 3 2 1

Sorting integer array to avoid repeating consecutive values in C

I'm using Linux to implement this sorting. If I have a array arr[] ={1, 1, 1, 2, 2, 3, 3}, how to sort it by this:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 1
arr[4] = 2
arr[5] = 3
arr[6] = 1
I Tried to do something like this:
for (int i = 0; i < size; i++)
{
if (arr[i] < arr[i+1])
{
}
}
Please give me some suggestions, thank you so much!
a hint
first you have to sort the array, then starting from 1 to (end-1) if active item equals to the last item move it to the end.
#include <stdio.h>
#include <stdlib.h>
/*__________________________________________________
*/
static int __cdecl sortCallback(int *i1,int *i2){
return (*i1<*i2)?-1:(*i1>*i2)?1:0;
}
/*__________________________________________________
*/
void printArr(char* Title,int *arr,int n){
int i;
if(Title)
printf("%s:\n\t",Title);
for (i=0;i<n;i++)
printf("%d ",arr[i]);
printf("\n");
return;
}
/*__________________________________________________
*/
void arrange(int *arr,int n){
int i=1,j;
int a;
while(i<(n-1)){
if(arr[i]==arr[i-1]){
a=arr[i];
for(j=i;j<(n+1);j++){
arr[j]=arr[j+1];
}
arr[n-1]=a;
}else
i++;
}
}
/*__________________________________________________
*/
int main(void){
int arr[7];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 1;
arr[4] = 2;
arr[5] = 3;
arr[6] = 1;
printArr("Initial",arr,7);
qsort(arr,7,sizeof(int),sortCallback);
printArr("Sorted",arr,7);
arrange(arr,7);
printArr("Rearranged",arr,7);
return 0;
}
#include <stdio.h>
void cnv(int n, int arr[n]){//arr is sorted
struct {
int value;
int occurs;
} tmp[n];
//make distinct array
int k = 0;
tmp[k].value = arr[0];
tmp[k].occurs = 1;
for(int i = 1; i < n; ++i){
if(arr[i] != arr[i-1]){
tmp[++k].value = arr[i];
tmp[k].occurs = 1;
} else {
++tmp[k].occurs;
}
}
//Written back
for(int i = 0, j = 0; i < n; ++i){
while(tmp[j].occurs == 0){
j = (j == k) ? 0 : j + 1;
}
arr[i] = tmp[j].value;
--tmp[j].occurs;
j = (j == k) ? 0 : j + 1;
}
}
int main(void){
int arr[] ={1, 1, 1, 2, 2, 3, 3};
int n = sizeof(arr)/sizeof(*arr);
cnv(n, arr);
for(int i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}

How to loop an array of integers and save both positive and negative into another array?

For example an array: {1, 2, 3}
How do I make a program that loops this array to get an output of {1, -1, 2, -2, 3, -3}?
I tried doing something like:
#include <stdio.h>
int main()
{
int n = 3;
int arr[3] = {1, 2, 3};
int result[6];
int i, j, k;
for(i = 0; i < n*2; i++)
{
for(j = 0; j < n; j++)
{
for(k = 0; k < 2; k++)
{
if((i+1) % 2 != 0)
{
result[i] = arr[j];
}
else if((i+1) % 2 == 0)
{
result[i] = -arr[j];
}
}
}
}
for(i = 0; i < n*2; i++)
{
printf("%d ", result[i]);
}
}
But it only outputs {3, -3, 3, -3, 3, -3}
I thought my logic was perfect xD . Can anyone help?
Simple implementation: just store positive and negative values.
#include <stdio.h>
int main(void)
{
int n = 3;
int arr[3] = {1, 2, 3};
int result[6];
int i;
for (i = 0; i < n; i++)
{
result[i * 2] = arr[i];
result[i * 2 + 1] = -arr[i];
}
for(i = 0; i < n * 2; i++)
{
printf("%d\n", result[i]);
}
return 0;
}
This block seems to work:
int src[] = { 1, 2, 3};
int dest[(sizeof(src) / sizeof(int)) * 2];
int destCount = 0;
for (int i = 0; i < sizeof(src) / sizeof(int); i++) {
dest[destCount++] = abs(src[i]);
dest[destCount++] = -(abs(src[i]));
}
for (int i = 0; i < (sizeof(src) / sizeof(int)) * 2; i++) {
printf("%d\n", dest[i]);
}
I put in abs() calls to make sure you get a positive number followed by a negative number. If this isn't what you want, then just get rid of them.
Or if you just want output you could do this:
#include <stdio.h>
int main(void)
{
int n = 3;
int arr[3] = {1, 2, 3};
int i;
for (i = 0; i < n; i++)
{
printf("%d ",arr[i]);
printf("%d ",-1*arr[i]);
}
return 0;
}

Removing duplicated numbers in an array

#include <stdio.h>
int main()
{
int array[8] = {4, 1, 5, 4, 2, 7, 4, 2};
int i, j, k;
int len = 8;
for(i = 0; i < len; i++)
{
for(j = i + 1; j < len;)
{
if(array[j] == array[i])
{
for(k = j; k < len - 1; k++)
{
array[k] = array[k + 1];
}
len--;
}
else
{
j++;
}
}
for(i = 0; i < len; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
return 0;
}
Hi,
Above is the code to remove duplicated numbers in an array, but when compiles and executes, I get 4 1 5 2 7 2--which isn't right because I'm supposed to get 4 1 5 2 7.
It seems that I have a problem with len but couldn't figure out where and what in the code specifically needs to be fixed.
Don't know if it is a mistake in indentation, or you miss-copied the code from somewhere ?
anyways to get it run, make this minor changes and it runs (Don't expect an explanation I doubt you don't need it)
#include <stdio.h>
int main()
{
int array[8] = {4, 1, 5, 4, 2, 7, 4, 2};
int i, j, k;
int len = 8;
for(i = 0; i < len; i++)
{
for(j = i + 1; j < len;)
{
if(array[j] == array[i])
{
for(k = j; k < len - 1; k++)
{
array[k] = array[k + 1];
}
len--;
}
else
{
j++;
}
}
} // close the main `for` loop
// you used to print out after each iteration!
for(i = 0; i < len; i++)
{
printf("%d ", array[i]);
}
printf("\n");
return 0;
}

Resources