i am writing multikey quicksort,i compiles fine,but when i run ,stops working abnormaly,i think it loops for ever or something like this,how could i fix this?ones again when compile no problem,here is link for it
http://ideone.com/bBtaX
it writes runtime error,here is also code
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int min(int a,int b){
return a<=b?a:b;
}
#define swap(a,b){ char *t=x[a];x[a]=x[b];x[b]=t;}
#define i2c(i) x[i][depth]
void vecswap(int i, int j, int n, char *x[])
{
while (n-- > 0) {
swap(i, j);
i++;
j++;
}
}
void ssort1(char *x[],int n,int depth);
void ssort(char *x[],int n)
{
ssort1(x,n,0);
}
void ssort1(char *x[],int n,int depth){
int a,b,c,d,r,v;
if(n<=1)
return ;
a=rand()%n;
swap(0,a);
v=i2c(0);
a=b=1;
c=d=n-1;
for (;;)
{
while(b<=c && (r=i2c(b)-v)<=0){
if (r==0) {
swap(a,b);a++;
}
b++;
}
while(b<=c && (r=i2c(c)-v)>=0){
if (r==0) {
swap(c,d); d--;
}
c--;
}
if (b>c)
break;
swap(b,c);
b++;
c--;
}
r=min(a,b-a);
vecswap(0,b-r,r,x);
r = min(d-c, n-d-1);
vecswap(b, n-r, r, x);
r=b-a;
ssort1(x,r,depth);
if (i2c(r)!=0)
ssort1(x+r,a+n-d-1,depth+1);
r=d-c;
ssort1(x+n-r,r,depth);
}
int main(){
char *s[]={"dato","giorgi","beso","computer","deda","kata","spilo"};
int n=sizeof(s)/sizeof(char);
ssort(s,n);
for (int i=0;i<n;i++)
cout<<s[i]<<" "<<endl;
return 0;
}
This:
int n=sizeof(s)/sizeof(char); /* Would return 28, resulting in out of bounds
on array 's' in subsequent for loop. */
should be:
int n=sizeof(s)/sizeof(char*);
^
A safer way of determining the number of elements in an array is:
int n=sizeof(s)/sizeof(s[0]);
Related
I'm preparing for a programing test at my uni and i'd like to write a program in c which can compare two intervals. I've tried many strategies but nothing seems to quite work properly.I believe there is an issue within my if parameters.
#include <stdio.h>
#include <stdlib.h>
//functions
int io_menu(int a,int b);
int int_check(int k,int n);
int basic_ui(int k,int n,int i,int j);
unsigned interval(int k,int n,int i,int j);
void printint(char str[]);
int main()
{
int fir_beg,fir_last,sec_beg,sec_last;
do{
basic_ui(fir_beg,fir_last,sec_beg,sec_last);
}while(int_check(fir_beg,fir_last)==0 || int_check(sec_beg,sec_last)==0);
return 0;
}
//menu for print and scan
int io_menu(int a,int b)
{
printf("Give Begining number: ");
scanf("%d",&a);
getchar();
printf("Give Ending number: ");
scanf("%d",&b);
getchar();
}
//integer check
int int_check(int k,int n){
if(n > 0 && k > 0){return 1;}
else{return 0;}
}
//main menu
int basic_ui(int k,int n,int i,int j)
{
char frst[]="first";
char scnd[]="second";
printint(frst);
io_menu(k,n);
printint(scnd);
io_menu(i,j);
if (int_check(k,n)==1 && int_check(i,j)==1)
{
printf("Data is correct,please wait\n");
interval(k,n,i,j);
}
else{
printf("Unable to calculate,please try again later\n\n");
}
}
//calculation for the intervals
unsigned interval(int k,int n,int i,int j)
{
if(k!=n && i!=j){
if(n<i)
{
printf("Before");
}
else if(k>j)
{
printf("After");
}
else if(i=k && n>i)
{
printf("Meets");
}
else if(i=n && k<i)
{
printf("Met By");
}
else if(k<i && n>i)
{
printf("Overlaps");
}
else if(k<j && n>j)
{
printf("Overlapped by");
}
else if(k>i && n<j)
{
printf("Strict during");
}
else if(k<i && n>j)
{
printf("Strict Contains");
}
else if(k=i && n<j)
{
printf("Start");
}
else if(k=i && j>n)
{
printf("Started By");
}
else if(n=j && i<k)
{
printf("Finishes");
}
else if(n=j && i>k)
{
printf("Finished by");
}
else if(n=j && i=k)
{
printf("Equal");
}
}
else{printf("Unable to calculate,please try again later\n\n");}
}
void printint (char str[])
{
printf("Enter for %s interval\n",str);
return 0;
}
To be more specific k,n are the beginning and ending numbers for the first interval as well as i,j are for the second one. Please try to understand that it is my 3d week familiarising with the c language as well as with programing in general.
I'm pretty new to C so be gentle, somewhy my code doesn't work, be kind and help my figure it out why it doesn't, also if it's possible to make it shorter without making it too complicated, please help in that too.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "swap.h"
#include "magic.h"
int main(int argc, char *argv[])
{
int i,j,count;
int min=atoi(argv[1]);
int max=atoi(argv[2]);
if(min>max)
{
swap(&min, &max);
}
if (min<0)
{
min=1;
}
if(argc<2 || argc>5){exit(EXIT_FAILURE);}
else
{
magic();
}
}
Magic.c
#include <stdlib.h>
#include <stdio.h>
#include magic.h
magic(char *argv[])
{
for(i = min; i<=max; i++)
{
count = 0;
for(j=2; j<=i/2; j++)
{
if(i%j==0)
{
count++;
break;
}
}
if(count==0 && i!= 1 && i!= 0)
printf("%d \n",i);
}
return 0;
}
this is as single file for simplicity
#include <stdio.h>
#include <stdlib.h>
void swap(int *a,int *b){
int c=*a;
*a=*b;
*b=c;
}
void magic(int min, int max);
int main(int argc, char *argv[])
{
int min,max;
if(argc!=3) // (argc<2 || argc>5)
exit(EXIT_FAILURE);
min=atoi(argv[1]);
max=atoi(argv[2]);
if(min>max)
swap(&min, &max);
if (min<0)
min=1;
magic(min,max);
return EXIT_SUCCESS;
}
void magic(int min, int max){
int i,j,count;
for(i = min; i<=max; i++){
count = 0;
for(j=2; j<=i/2; j++) {
if(i%j==0){
count++;
break;
}
}
if(count==0 && i!= 1 && i!= 0)
printf("%d \n",i);
}
}
You have some error in your code :
you are trying to use the variables min, max and countin your function magic however since they are declared in your main function magic does not have knowledge of them.
you should change your main function like :
#include <stdio.h>
#include <stdlib.h>
#include "swap.h"
#include "magic.h"
int main(int argc, char *argv[])
{
int min=atoi(argv[1]);
int max=atoi(argv[2]);
if(min>max)
{
swap(&min, &max);
}
if (min<0)
{
min=1;
}
if(argc<2 || argc>5){exit(EXIT_FAILURE);}
else
{
magic(min, max);
}
return EXIT_SUCCESS;
}
and your magic function :
#include <stdlib.h>
#include <stdio.h>
#include "magic.h"
int magic(int min, int max)
{
int count;
for(int i = min; i<=max; i++)
{
count = 0;
for(int j=2; j<=i/2; j++)
{
if(i%j==0)
{
count++;
break;
}
}
if(count==0 && i!= 1 && i!= 0)
printf("%d \n",i);
}
return 0;
}
In the main function I change magic(); by magic(min, max); to pass parameters to the function which can be retrieve in magic with it's new signature int magic(int min, int max).
Since your magic function return an integer don't forget to specify the return value in the signature of your function.
I'm 2nd year computer engineer and still in learning process of C language. I'd like to undesrtand how to dynamically alocate an array by using function instead of allocate inside the main.
Here is the code that works when I allocate array inside main.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#define ESC_KEY 27
#define NUM_1_KEY 49
#define NUM_2_KEY 50
void find_two_largest(int a[], int n, int *largest, int *second_largest);
void arrayInit(int *,int *, int, int);
void randGenArray(int [], int);
void inputArray(int[], int);
void result(int, int);
void loading(void);
int menu(void);
int main(void)
{
system("color f5");
int n,i,largest,largest_2, *a;
arrayInit(a,&n, 2, 10);
if(menu())
randGenArray(a,n);
else
inputArray(a,n);
find_two_largest(a,n,&largest,&largest_2);
result(largest,largest_2);
return 0;
}
void find_two_largest(int a[], int n, int *largest, int *second_largest)
{
int i=0,j=0;
system("cls");
loading();
*largest = 0;
*second_largest = *largest;
for (i=1;i<n;i++){
if(*largest<a[i])
*largest=a[i];
}
for(j=1;j<n;j++){
if(*largest==a[j])
continue;
else{
if(*second_largest<a[j])
*second_largest=a[j];
}
}
return;
}
void randGenArray(int a[], int n)
{
srand(time(NULL));
int i;
for(i=0; i<n; i++){
a[i]=rand()%100;
Sleep(10);
printf("\n>> Integer %d: %d", i+1, a[i]);
}
printf("\n\n\nPress any key to continue...");
getch();
return;
}
void inputArray(int a[], int n)
{
int i;
for(i=0; i<n; i++){
printf("\n Please enter integer %d: ", i+1);
scanf("%d",&a[i]);
}
return;
}
int menu(void)
{
char _char;
printf("\n Please choose one of the following options:\n 1.Fill array manually\n 2.Fill array by random numbers\n\n ");
while(1)
{
_char = getch();
switch(_char)
{
case ESC_KEY:
printf("\n\n Thank you for using our software!\n\n");
exit(0);
case NUM_1_KEY:
system("cls");
return 0;
case NUM_2_KEY:
system("cls");
return 1;
default:
break;
}
}
}
void arrayInit(int *a,int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
a = (int*)calloc(*n,sizeof(int));
return;
}
void loading(void)
{
printf("\n Loading");
printf(".");
Sleep(300);
printf(".");
Sleep(300);
printf(".");
Sleep(300);
system("cls");
return;
}
void result(int l, int l2)
{
system("cls");
printf("\n Largest = %d Second Largest = %d",l,l2);
Sleep(500);
printf("\n\n\n Thank you using our software! ;D\n\n");
return;
}
But if you cut and paste this line from arrayInit to main and change *n to n - it will work!
a = (int*)calloc(*n,sizeof(int));
I'm sorry for asking about so stupid and obvious things but I didn't figure it out by myself. Thank you for any advice.
Here is a simple program which will show you how to do that -
#include <stdio.h>
#include <stdlib.h>
void create(int **p,int n); // function taking arguments as int ** and n is number of elements
int main(void) {
int *a;
int n=5,i; // declare and initialize n
create(&a,n); // pass address of a to function
for(i=0;i<n;i++){
a[i]=i; // store value of i in a[i]
printf("%d\n",i); // print a[i]
}
free(a); // free the allocated memory
return 0;
}
void create(int **p, int n){
*p=calloc(n,sizeof(int)); // allocate memory to *p (type- is int *)
}
Working Code
You must change your function return type
void * arrayInit(int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
return calloc(*n,sizeof(int));
}
And call it from main in this way: a = arrayInit(&n, 2, 10);
If the OrderString is ”dcfbae”, it means d > c > f > b > a > e, unlike the lexicographic(dictionary)
ordering where we have a > b > c > d > e > f.
all are lower case alphabets.
I'm getting SEG FAULT..i know its somewhat related to pointers but i'm unable to figure it out..
here's my code :
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MAX 1001
int min(int x,int y){
return (x>y)?y:x;
}
int check(char a,char b,char *order){
int i,x,y;
for(i=0;i<strlen(order);i++){
if(a==order[i])
x=i;
if(b==order[i])
y=i;
}
if(x>y)
return 1;
else
return 0;
}
int compare(char *a,char *b,char *order){
int i=0,l1=strlen(a),l2=strlen(b);
for(i=0;i<min(l1,l2);i++){
if(a[i]==b[i])
continue;
else{
if(check(a[i],b[i],order)==1)
return 1;
else
return 0;
}
}
}
void merge(int l,int r,int mid,char **string,char *order){
int size1=mid-l+1;
int size2=r-mid;
char a[size1][MAX],b[size2][MAX];
int i,j,k;
for(i=0;i<size1;i++)
strcpy(a[i],string[l+i]);
for(i=0;i<size2;i++)
strcpy(b[i],string[mid+1+i]);
i=0;
j=0;
k=0;
while(i<size1 && j<size2){
if(compare(a[i],b[j],order)==0){
strcpy(string[k],a[i]);
i++;
}
else{
strcpy(string[k],b[j]);
j++;
}
k++;
}
while(i<size1){
strcpy(string[k],a[i]);
i++;
k++;
}
while(j<size2){
strcpy(string[k],b[j]);
j++;
k++;
}
}
void mergesort(int l,int r,char **string,char *order){
int mid=(l+r)/2;
if(l<r){
mergesort(l,mid,string,order);
mergesort(mid+1,r,string,order);
merge(l,r,mid,string,order);
}
return ;
}
int main(){
char order[MAX];
scanf("%s",order);
int T;
scanf("%d",&T);
char string[T][MAX];
int i;
for(i=0;i<T;i++)
scanf("%s",string[i]);
mergesort(0,T-1,string,order);
for(i=0;i<T;i++)
printf("%s\n",string[i]);
return 0;
}
i'm using mergesort algorithm..
thanks in advance :)
You declare your mergesort() as follows:
void mergesort(int l,int r,char **string,char *order)
But then you invoke it as follows:
mergesort(0,T-1,string,order);
Where string is defined as follows:
char string[X][Y];
So, this is wrong: your mergesort expects a pointer to an array of pointers to char, and you are passing it an array of char.
And if your compiler is not giving you an error, or at least a warning for this, then this means that you are trying to develop software without the bare minimum warnings enabled, or you are using your compiler in some compatibility mode for some paleolithic version of C. Which is a lost cause. So, before fixing anything, before even touching your code again, figure out how to enable all warnings on your compiler, or how to get your compiler to compile for the latest C standard.
To fix this, you could either do what #kkk suggested, which tough might be a bit of work, because you'd have to fix the way your mergesort function works, or you could try to declare your string variable as follows: char** string; Then, you would have to allocate memory for it, with something like this: string = malloc( T * sizeof char* ); and then, right before reading each string, allocate each string like this: string[i] = malloc( (MAX + 1) * sizeof char ); I don't have a C compiler handy, so I can't verify that I got the syntax exactly right, but this should help you get started.
If the purpose is to avoid a crash or segfault avoid warnings first.
by the way char ** and char [][] are not different.
change this
void merge(int l,int r,int mid,char **string,char *order){
to
void merge(int l,int r,int mid,char string[][MAX],char *order){
and this
void mergesort(int l,int r,char **string,char *order){
to
void mergesort(int l,int r,char string[][MAX],char *order){
Now you'll run into not working state
Well I do not Understand your code but at least I can give you a code with no errors and you can check where is the problem in your code.
If you get wrong Answer it happens because you coded wrong.
Here is the code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MAX 1001
int min(int x,int y){
return (x>y)?y:x;
}
int check(char a,char b,char *order){
int i,x=0,y=0;
for(i=0;i<(int)strlen(order);i++){
if(a==order[i])
x=i;
if(b==order[i])
y=i;
}
if(x>y){
return 1;
}else{
return 0;
}
}
int compare(char *a,char *b,char *order){
int i=0,l1=(int)strlen(a),l2=(int)strlen(b);
for(i=0;i<min(l1,l2);i++){
if(a[i]==b[i]){
continue;
}else{
if(check(a[i],b[i],order)==1){
return 1;
}
}
}
return 0;
}
void merge(int l,int r,int mid,char string[][MAX],char *order){
int size1=mid-l+1;
int size2=r-mid;
char a[size1][MAX],b[size2][MAX];
int i,j,k;
for(i=0;i<size1;i++){
strcpy(a[i],string[l+i]);
}
for(i=0;i<size2;i++){
strcpy(b[i],string[mid+1+i]);
}
i=0;
j=0;
k=0;
printf("before :\n");
for(i=0;i<size1+size2;i++)
printf("%s\n",string[i]);
while(i<size1 && j<size2){
if(compare(a[i],b[j],order)==0){
strcpy(string[k],a[i]);
i++;
}else{
strcpy(string[k],b[j]);
j++;
}
k++;
}
while(i<size1){
strcpy(string[k],a[i]);
i++;
k++;
}
while(j<size2){
strcpy(string[k],b[j]);
j++;
k++;
}
}
void mergesort(int l,int r,char string[][MAX],char *order){
int mid=(l+r)/2;
if(l<r){
mergesort(l,mid,string,order);
mergesort(mid+1,r,string,order);
merge(l,r,mid,string,order);
}
}
int main(void){
char order[MAX];
int t,i;
if(scanf("%s",order) != 1){
exit(1);
}
if(scanf("%d",&t) != 1){
exit(1);
}
char string[t][MAX];
for(i=0;i<t;i++)
if(scanf("%s",string[i]) != 1){
exit(1);
}
mergesort(0,t-1,string,order);
return 0;
}
Output:
michi#michi-laptop:~$ ./program
acb
2
cab
bac
before :
cab
bac
This is an extended question from
How can i remove this Segmentation fault in C Program
here segmentation fault occur because of stack overflow due to recursion so manny times
so i have changed his code like this..
make a MACRO insted of that function so function call is removed
#include <stdio.h>
static inline void p(char *a, int b);
#define MAGIC(a,b) p(a,b)
void p(char *a, int b)
{
static long int i = 0;
if (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
return MAGIC(a, b);
} else
{
return;
}
}
int main()
{
char *a = "HI";
int b = 10;
MAGIC(a, b);
printf("\nComplete");
return 0;
}
still i am getting segmentation fault ...still stack overflow.... why?
Change return MAGIC(a, b); to
goto START; and add a START label in the beginning of the function.
Edit:
Example using a while loop:
void p(char *a, int b)
{
static long int i = 0;
while (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
}
}
Example using a for loop:
void p(char *a, int b)
{
long int i = 0; // static seems wrong here
for (;i != 350000; i++)
{
printf("\n%ld \t at Hi hello", i);
}
}
No, it will not work. A macro is just a text copy-paste, so the result is still the same.
So your code will be expanded as:
void p(char *a, int b)
{
static long int i = 0;
if (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
return p(a, b);
} else
{
return;
}
}
int main()
{
char *a = "HI";
int b = 10;
p(a, b);
printf("\nComplete");
return 0;
}
which still has the recursion and will likely stackoverflow.
EDIT : One way to redesign the algorithm is as follows:
void p(char *a, int b)
{
long int i = 0;
while (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
}
}