I have been trying to write the Radix sort algorithm in C.
When I run my code with base 10 it works fine for all inputs, however, with base 16 it sorts only the first 10 elements correctly. In addition, for any other base it is not working.
I would like to make an implementation that generalize for any base.
Here is the code a have so far, could you find any issues?
#include <stdio.h>
#include <stdlib.h>
int size=32;
int getMax(int arr[], int n) {
int mx = arr[0];
int i;
for (i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
void countSort(int arr[], int n, int exp, int base) {
int output[n];
int i;
int count[base];
memset(count,0,sizeof count);
for (i=0;i<n;i++)
count[(arr[i]/exp)%base]++;
for (i=1;i<base;i++)
count[i]=count[i]+count[i-1];
for (i=n-1;i>=0;i--) {
output[count[ (arr[i]/exp)%base ]-1]=arr[i];
count[ (arr[i]/exp)%base ]--;
}
for (i=0;i<n;i++)
arr[i]=output[i];
}
void radixsort(int arr[],int n,int base) {
int exp;
int m=getMax(arr,n);
for (exp=1;m/exp>0;exp=exp*10)
countSort(arr,n,exp,base);
}
int main(int argc,char *argv[]) {
int num,i=0,j,n,m;
int *arr,*newarr=NULL;
FILE *fp1;
FILE *fp2;
int base=atoi(argv[1]);
fp1=fopen(argv[2],"r");
if (fp1 == NULL) {
printf("Warning:File does not exists;please enter valid file name");
exit(0);
}
fp2=fopen(argv[3],"w");
if (fp2 == NULL) {
printf("Warning:File does not exists");
exit(0);
}
arr= malloc(sizeof(int)*size);
fprintf(fp2,"before sorting:");
while(fscanf(fp1,"%d",&num)==1) {
if(i<size) {
arr[i]=num;
i++;
fprintf(fp2,"%d ",num);
n=i;
} else {
newarr = malloc(sizeof(int)*2*size);
for(m=0;m<size;m++) {
newarr[m]=arr[m];
}
free(arr);
size=size*2;
arr=&newarr[0];
}
}
radixsort(arr,n,base);
fprintf(fp2,"\nAfter Sorting:");
for (j=0;j<n;j++)
fprintf(fp2,"%d ",arr[j]);
fclose(fp1);
fclose(fp2);
return 0;
}
Looks like for (exp=1;m/exp>0;exp=exp*10)is the problem. I think you need to use base instead of 10.
EDIT: I tried compiling and running this code and was not able to get it to work, even for base 10.
Related
Basically this problem asks me to get an input of target_sum and check the integers in the array. If a sum of a pair is equal to target_sum, I need to print it.
I wrote the code like this but it does not work. Where did I make the mistake?
void findPair (int arr[],int size,int target_sum)
{
int i,j;
for (i=0;i<size;i++){
for (j=0;j<size;j++){
if (arr[i] + arr[j] == target_sum)
{
printf("(%d,%d)",arr[i],arr[j]);
}
else
{
printf("No pair.");
}
}
}
}
int main(){
int arr[] = {8,7,2,5,3,1};
int target_sum;
printf("Enter target sum: ");
scanf("%d",target_sum);
findPair(arr,6,target_sum);
}
As #nsilent22 suggested, scanf("%d",target_sum); should be changed into scanf("%d",&target_sum);. Besides that, you could have the second for loop start at j=i+1, making your code overall look like this:
#include <stdio.h>
void findPair (int arr[],int size,int target_sum)
{
int i,j;
for (i=0;i<size;i++)
for (j=i+1;j<size;j++)
if (arr[i] + arr[j] == target_sum)
printf("\n(%d,%d)",arr[i],arr[j]);
else
printf("\nNo pair.");
}
int main(){
int arr[] = {8,7,2,5,3,1};
int target_sum;
printf("Enter target sum: ");
scanf("%d",&target_sum);
findPair(arr,6,target_sum);
}
This is the code i wrote for multiple occurrences in linear search.Can you please help me point out the mistake ? I want the function to store multiple values in the pointer array and then later to print the array
#include <stdio.h>
void linearsearch(int n,int a[n],int x,int count,int *b[count])
{
count=0;
int i;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
b[j]=i;
j++;
}
}
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int x;
scanf("%d",&x);
int count;
int *b[count];
linearsearch(n,a,x,count,b);
for(i=0;i<count;i++)
{
printf("%d",*b[i]);
}
return 0;
}
I think there are several errors.
count must be initialized, like int count = 0;
count variable is not changed after linearsearch function.
b array should allocated dynamically.
suggested patch is:
#include <stdio.h>
void linearsearch(int n,int a[n],int x,int *count,int **b)
{
count=0;
int i;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
*b = realloc(*b, sizeof(int) * (j + 1));
(*b)[j]=i;
j++;
}
}
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int x;
scanf("%d",&x);
int count = 0;
int *b = NULL;
linearsearch(n,a,x,&count,&b);
for(i=0;i<count;i++)
{
printf("%d",b[i]);
}
return 0;
}
Well the ideal way would be to allocate the memory dynamically based of the number of x found. But well let's look at the errors first. Maybe after this discussion you can write the code.
b[j]=i;
In the called function let's dissect the type of this.
i is of type int. And b[j] is of type int*. Then you assigned them (type mismatched). Then %d expects an int but you passed something of type int*. This is undefined behavior.
Now there was another flaw you had - you passed count and somehow you expect the value you changed in search will be there in main(). C is pass by value and you changed to a local variable. That change is lost when the called function ends.
#include <stdio.h>
#include <stdlib.h>
int* linearsearch(int n,int* a,int x,int* count)
{
*count=0;
if( n <= 0){
fprintf(stderr, "%s\n","Error" );
exit(1);
}
int *t = malloc(sizeof(*t)*n);
if( t == NULL){
perror("Malloc failed");
exit(1);
}
for(int i = 0; i < n; i++)
if(a[i] == x)
t[(*count)++] = i;
int *temp = realloc(t,sizeof(*temp)* (*count));
if( temp == NULL){
perror("Realloc failed");
exit(1);
}
t = temp;
return t;
}
int main(void)
{
int n;
if( scanf("%d",&n)!= 1){
fprintf(stderr, "%s\n", "Error in input");
exit(1);
}
if( n <= 0 ){
fprintf(stderr, "%s\n", "Error in input : must be greater than 0");
exit(1);
}
int a[n];
for(int i=0; i < n; i++)
if(scanf("%d",&a[i])!=1){
fprintf(stderr, "%s\n","Error in input." );
exit(1);
}
int elmt_to_find;
if( scanf("%d",&elmt_to_find)!= 1){
fprintf(stderr, "%s\n", "Error in input : Element to find(must be integer)");
}
int count;
int *b = linearsearch(n,a,elmt_to_find,&count);
for(int i = 0; i < count; i++)
printf("%d ",b[i]);
printf("%s","\n");
free(b);
return 0;
}
If you want to stick with using VLA for b, you can alter your linearsearch to return count only if b is NULL. Then, you can create b as VLA, and pass it back to linearsearch again to be populated.
int count = linearsearch(n, a, x, 0, 0);
int b[count];
linearsearch(n, a, x, count, b);
Then, your function could look like:
int linearsearch(int n,int a[n],int x,int count,int *b[count])
{
int i;
if(count==0)
{
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
}
if (b==0)
{
return count;
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
b[j]=i;
j++;
}
}
return count;
}
this is my code
#include <stdio.h>
void show(int*,int);
int sort (int*,int);
int BinSearch(int[],int,int);
int Insertelem(int*,int,int,int*);
int main(void)
{
int array[100]={15,30,40,10,25,5,35,20,45};
int len=9;//length
int *pos=0;//position
int elem=0;//element
int ok=0;
printf("array : ");
show(array,len);
sort(array,len);
printf("array after sorting : ");
show(array,len);
printf("enter the number you want to add :");
scanf("%d",&elem);
*pos=BinSearch(array,elem,len);
ok=Insertelem(array,len,elem,pos);
show(array,len);
return 0;
}
void show(int *array,int len)//print the array
{
for(int i=0;i<len;i++)
{
printf("%d,",array[i]);
}
printf("\n");
}
int sort(int *array,int len)//sort the array
{
int help=0;
for(int i=len-1;i>0;i--)
{
for(int j=0;j<i;j++)
{
if(array[j]>array[j+1])
{
help=array[j];
array[j]=array[j+1];
array[j+1]=help;
}
}
}
return *array;
}
int BinSearch(int array[100],int elem,int len)//searching for the position
{
int first=1;
int last=len-1;
int middle=(first+last)/2;
int pos;
while(first<=last)
{
if(elem<array[middle])
{
last=middle-1;
middle=(first+last)/2;
}
else if(elem>array[middle])
{
first=middle+1;
middle=(first+last)/2;
}
else if(elem==array[middle])
{
break;
}
}
pos=array[middle]+1;
return pos;
}
int Insertelem(int *array,int len,int elem,int *pos)//inserting the element
//in the right position
{
len++;
for(int i=len-1;i>*pos+1;i--)
{
array[i+1]=array[i];
}
elem=array[*pos];
return *array;
}
note : there is no compiler error
I think the problem is in the binsearch function or Insertelem function because I tested all other functions and they are working as expected
when I run this code it works so good until the user enter the element he wont and the program just crash
int pos=-1;//change not pointer
...
pos=BinSearch(array,elem,len);
ok=Insertelem(array,len,elem,&pos);//pos is no need for a pointer, because since not changed.
len += 1;//The length must be changed(or by inside Insertelem)
...
int BinSearch(int array[100],int elem,int len)//searching for the position
{
int first=0;//not 1
...
pos=first;//not midlle, not element of array(array[middle])
return pos;
}
int Insertelem(int *array,int len,int elem,int *pos)
{
...
for(int i=len-1;i>= *pos;i--)//not i>*pos+1
...
array[*pos]=elem;//not elem=array[*pos];
return *array;//??
}
#include <stdio.h>
int factor_power(int n,int d);
int main()
{
int input;
do
{
printf("Enter an integer (> 1): ");
scanf("%d",&input);
}while(input<2);
printf("%d = ", input);
int current=input;
int i;
for(i=2; i<=current; i++)
{
int power=power_factor(current,i);
if(power!=0)
{
current=(int) (current/pow(i, power));
printf("%d^%d * ",i,power);
}
}
return 0;
}
int power_factor(int n, int d)
{
int power=0;
if(d<=n)
{
while(n%d==0)
{
power++;
n=n/d;
}
return power;
}
return 0;
}
Hello, I am new to C. I have a problem with the output of the code above. If you run the code you will see there is a extra * at the end of the output. Since C doesnt have a string class, how could I get rid of the * at the end. I know appending string is a options but is there a quicker and efficient way of solving this problem?
Print the * in an alternative way.
int current=input;
int i;
int first_term = 1;
for(i=2; i<=current; i++)
{
int power=power_factor(current,i);
if(power!=0)
{
current=(int) (current/pow(i, power));
if (!first_term)
printf(" * ");
first_term = 0;
printf("%d^%d",i,power);
}
}
This program is to find three four digit prime numbers, such that they are permutations of each other and have a difference of 3320 between them. Now the following program correctly produces the prime numbers but execution stops or just hangs after the value 1000. Why this happens and how can I correct it?
#include<stdlib.h>
#include<stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Bsearch(long int *primes,long int low,long int high,long int search)
{
while(low<=high)
{
long int mid=(low+high)/2;
if(search<primes[mid])
{
high=mid+1;
}
else if(search>primes[mid])
{
low=mid+1;
}
else if(search==primes[mid])
return 1;
}
return 0;
}
int checkPermu(long int *primes,long int i,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[i%10];prod2*=primes[j%10];prod3*=primes[k%10];
i/=10;j/=10;k/=10;
}
prod1*=primes[i];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}
There are many bugs in your code.
In the function Bsearch, you are searching for a value in the array. What if its not present? In your case, 1000 is not a prime number. So, you can't find that in the array. You are coming out of the loop only if the value matches exactly. which won't happen in this case ending up in an infinite loop
In the function, checkPermu, there are two variables declared as i. which means you are shadowing the i that is passed as parameter. To avoid it, give it some other name.
Now, to avoid the first case, you can use an inbuilt function in C++, lower_bound , or else modify the code correspondingly. Here is your edited code.
#include <stdlib.h>
#include <stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Binary_Search(long int a[], int low, int high, long int e)
{
if ( low < 0) return 0;
if (low>=high )
{
if ( e <= a[low] ) return low;
return low+1;
}
int mid=(low+high)/2;
if ( e> a[mid])
return Binary_Search(a,mid+1,high,e);
return Binary_Search(a,low,mid,e);
}
int Bsearch(long int *primes,long int low,long int high,long int search)
{
int idx = Binary_Search(primes, low, high+1,search);
if(primes[idx]==search)
return 1;
return 0;
}
int checkPermu(long int *primes,long int ii,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[ii%10];prod2*=primes[j%10];prod3*=primes[k%10];
ii/=10;j/=10;k/=10;
}
prod1*=primes[ii];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
//Bsearch(primes,1,count-1,1000);
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!\n");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!\n");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!\n");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!\n");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}
First, the reason for hang is probably due to this line:
long int primes[count];
count here is 78499 and you are allocating 313996 bytes on the stack. The stack size is probably smaller than this and the stack overflow seems to be causing problem with bash or cmd.exe in my case (blind guess, it's cmd.exe).
Changing that to
long int *primes = malloc(count * sizeof *primes);
resolves the issue.
The actual problem with your code however is that your binary search never terminates. So fixing the previous bug, your code is in an infinite loop, so you don't see any output. I recommend trying to figure out why your binary search doesn't terminate for practice, but in real life, use bsearch from the standard library.