Find longest word C with recursion - c

I'm trying to find the size of the longest word in an array of structs.
I have this array of structs:
struct Vocabolo{
char parola[20];
char *sinonimi[5];
char definizione[300];
};
typedef Vocabolo vocabolo;
vocabolo parole[30];
Now I have to use incremental recursion in order to find the size of the lognest word in the array. Words are contained each in:
parole[n].parola
I'm using this code:
int Lunghezza_parola(vocabolo *parole,int n){
int y;
if(n == 1)
return strlen(parole[0].parola);
else {
y = strlen(parole[n-1].parola);
return Scegli_max(y,Lunghezza_parola(&parole,n-1));
}
}
Wnere Scegli_max is:
int Scegli_max(int y, int lunghezzaStringa){
if (y >= lunghezzaStringa)
return y;
else
return lunghezzaStringa;
}
In this program the user has to insert words manually and each time a word is inserted, the program should put them in alphabetical order.
If I try to input something like "come" as parole[0].parola and "hi" parole[1].parola and start this function the result is 3. Also it seems to works only if the longest word is in the last position of the array.
Any idea?
PS: this is part of a longer programm so is impossible to write here all the code but i'm quite sure everithing works fine exept this function so the words are ordered correctly in the array of struct.

Your problem is return Scegli_max(y,Lunghezza_parola(&parole,n-1));
You call Lunghezza_parola giving it &parole which is already a vocabolo *parole so this becomes a vocabolo **parole and the pointer is now invalid.
Try changing your return to return Scegli_max(y,Lunghezza_parola(parole,n-1));

Your problem is the line return Scegli_max(y,Lunghezza_parola(&parole,n-1)); . remove the &.
You should pass the value of the pointer, not a pointer to it.

Related

Why is my for loop increasing the size of my array in C?

I'm trying to make a binary number calculator in c and I'm running into issues of my for loops doubling the size of my second array and adding the first array onto the end. I'm really confused because I thought you couldn't increase the size after already declaring it. It is happening in my equation reading function as well but in this ones complement function it's a bit simpler to see. Any ideas of how to fix this?the codethe output
welcome to stack-overflow. From next time please use inline code editor to put your code instead of images. I have taken effort put your code in the answer itself to explain the problem. Please consider this as courtesy. Its very unusual to do it. But as you are a new member, I'm doing it.
// Cole carson's original code from image:
char * onescomp(char x[16], char y[16]){
int i;
for(i=0;i<=15;i++){
if(x[i] == '0'){
y[i] = '1';
continue;
}
else if(x[i] == '1'){
y[i] = '0';
continue;
}
}
return y;
}
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[16];
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}
Answer:
You don't need continue; in if-else blocks.
You need to add '\0' in the last cell of cb3n array. so puts() knows when string ends & stop printing.
so to quickly fix this issue you can create array with extra cell and assign all values as '\0'. so after copying fifteen 1's there will be '\0' in the end. I think in your case those extra zeros being printed might be garbage values. It looks like array is doubling but it isn't, its just printing values beyond allocated memory because '\0' has not been provided.
//Quick fix
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[17]={'\0'}; // <--- quick fix
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}

Why is binary search function not working when values on pointers are compared instead of the pointers themselves?

I was making this binary search function in c, but have encountered a problem. I have passed a pointer of a sorted array, its (size-1) and the number to be searched. When I try to compare values at the front position and last position in the while loop, its not working for the values on the right of middle element. For eg, if I pass a array={1,2,3,4,5} for {1,2,3}, the function works fine, however for {4,5} the loop just runs once and exits.
There's one more issue, this problem only happens if we compare the values on the address of the pointers, but if I compare the pointers instead, the function works perfectly. Better explained in the code given below.
int binarysearch(int*p,int r,int num){
//p is pointer of an array, r is the (sizeof(array)-1), num is the number to be searched
int *mid;
while(*p<=*(p+r)){//if we replace the condition with(p<=(p+r)) the function works
mid=(p+(r/2));
printf("1 ");
if(*mid==num)
return *mid;
if(*mid<num)
p=mid+1;
else
r=((r/2)-1);
}
return -1;
}
Check out the way you calculate the mid value.
In the first iteration, mid=(p+(r/2)) will give you the middle term correctly. Let say r=5, and that in the first iteration we got *mid<num so now p=mid+1 or p=p+3.
The problem now is that r is still 5 so the array pointer just got shifted away from its values without marking the new end. This can easily lead to segmentation fault if you will try to use your result address later.
the solution is simple: don't calculate the mid position with a pointer and int. Use two pointers to mark the search bounders or two integers to mark their indexes.
You can also use your way, but be sure to update r size every iteration.
First option - using indexes (my choice if I had to make one):
int binarysearch(int*p,int r,int num){
int mid;
int a=0;
while(a<=r) {
mid=(a+r)/2;
printf("1 ");
if(p[mid]==num)
return *mid;
else if(p[mid]<num)
a=mid+1;
else if(a==r)
break;
else
r=mid;
}
return -1;
}
Second option - your fixed version:
int binarysearch(int*p,int r,int num){
int *mid;
while(r>=0) {
mid=p+(r/2);
printf("1 ");
if(*mid==num)
return *mid;
else if(*mid<num) {
p=mid+1;
r-=(r/2)+1;
}
else if (r==0)
break;
else
r/=2;
}
return -1;
}

Issue about Binary search algorithm in c

I am confused in understating the behavior of the code while searching for an element which does not exist in the array.
The result of the element index i am looking for is always zero while declaring it as int index;.
The result of the element index i am looking for is random number while declaring it as size_t index;
what is the difference between declaring the variable index as int index; andsize_t;in the code below.
The code
#include <stdio.h>
#define SIZE 5
int main(void)
{
int numbers[SIZE]={1,2,3,4,5};
int search =0; // This variable define the required number i am searching for
int start = 0 ;
int end = SIZE-1 ;
size_t index;
while (start <= end)
{
int middle = (start+end)/2;
if (search == numbers[middle])
{
index = middle;
}
if (search > numbers[middle])
{
start = middle+1 ;
}
else
{
end= middle-1 ;
}
}
printf("The index of the element is %d",index);
return 0;
}
The basic problem is that index is not initialized and that it never gets assigned when you don't find what you are searching for. Since the printf statement accesses an uninitialized variable in that case, your code have undefined behavior, i.e. anything may happen - including print of all sorts of numbers.
The result of the element index i am looking for is always zero while declaring it as int index;
That is "just by luck"
The result of the element index i am looking for is random number while declaring it as size_t index;
That is also "just by luck"
Here are a couple of action items you can take to improve your code:
Since this array is statically defined there is no need to include the SIZE define inside the []. Declare it like this int numbers[]={1,2,3,4,5}; instead of this int numbers[SIZE]={1,2,3,4,5};. Let the compiler do the math for you.
Initialize index to some value (i.e. index = 0;). this is the main cause of the problem and it is introducing undefined behavior to the program.
Change the type of size_t index to int index every variable that was declared in the program is an int and the program is treating index as an int. So it might as well be an int to avoid confusion.
Make this an else if clause instead of just an if:
else if (search > numbers[middle])
{
start = middle+1 ;
}
Add another case to have the program fail gracefully when the value to be searched is missing from the data set. Such as, printf("Data not found: %d", search);
The algorithm still isn't 100% and has some flaws but I will leave this up to you to figure out. I hope this info helps!
Best Regards!
The problem is that , the value of indexis not initialized.
initializing the variable to 0 does not solve your problem.
Because you are using index to return the position of the array element.
By initializing the index = 0 will provide he same result for the elements not present in the array as well as the for the first element to the of the array .
The better way is to initialize as size_t index = -1;
So that the result for the elements not present in the array would b -1.
Also check for the access specifier used in the printf statement, for size_t datatype. It can be ,
printf("The index of the element is %ld",index);
You are not using correct specifier for size_t, it's not %d.
Try to use %zd or %ld and it'll work fine.
Furthermore, add this after the while loop so that it doesn't show weird value of index when the element is not present in the array.
if(start>end) {
printf("That number is not present in the array");
return 0;
}
And move the line printf("The index of the element is %d",index); under the condition if (search == numbers[middle]). So that you don't get "this number is not present" even if it is present in the array.
For corrected version of your code see https://code.hackerearth.com/80043dg?key=7b325b26aec0f5425b76cc3efbdc93cf

Printing longer than calculated Average words in C program

I have a program that currently reads in words to a variable *char wordlist[lengthOfArray]; So basically it holds char word[10]. I can calculate average word lengths successfully, but I have a method that I want to print the words longer than this average recursively
void printAverage(char *wordlist, int n, int average){
if (n > 0){
if (strlen(wordlist[0]) > average){
printf("%s\n", wordlist[0]); // Print the one longer than average then move on
printAverage(wordlist + 1, n-1, average);
}
else {
printAverage(wordlist+1, n-1, average);
}
}
}
I have looked for hours online to see what is wrong, but for some reason, the comparison
if (strlen(a[0]) > average) isn't getting the value of my word correctly, and giving me the error
passing arg 1 of strlen makes pointer from Integer without a cast.
Does anyone have any idea how exactly I can do this correctly? Thanks in advance for any help, I am just stuck and I have already tried many things to no avail.
Your variable wordlist is not an array of words - it is a string. If you have an array of words it's either a 2D array like this:
char *wordlist[]
Or this:
char wordlist[][10]
Or a double-pointer like this:
char **wordlist
You need to set up the parameter according to the actual data you are passing into it.
You are declaring wordlist as a pointer to char instead of pointer to pointer to char.
char is an integral type so when you dereference it as wordlist[0] and pass it to strlen() the compiler warns you about passing an integral type instead of a pointer.
Try:
void printAverage(char **wordlist, int n, int average)
{
if (n > 0){
if (strlen(wordlist[0]) > average){
printf("%s\n", wordlist[0]); // Print the one longer than average then move on
}
printAverage(wordlist + 1, n-1, average);
}
}

Binary search, strcmp two dynamic arrays of strings in C

I'm fairly new to C programming but trying my best to understand it. I have two dynamic strings that are populated from two plain text files. One being a form of a dictionary, and the other one just a user input. What I want to get is binary search each user input word in the dictionary and find out if it is present (sort of a spell checker I guess).
I'm stuck on my binary search function:
char **dictElem;
int dictSize;
char **inputElem;
int binsearch(const char *val){
int pos;
int beg=0;
int end=dictSize-1;
int cond=0;
while (beg<=end){
pos=(beg+end)/2; //Jump in the middle
if ((cond=strcmp(dictElem[pos],val)) == 0)
return pos;
else if (cond<0)
beg=pos+1;
else
end=pos-1;
}
return 0;
}
Both dictElem and inputElem were already read by other methods and (let's say) both [0] elements are equal strings "aa".
However after I run the binsearch(inputElem[0] it always returns 0. I tried just strcmp(dictElem[0],inputElem[0]) and it returns 1.
Where am I going wrong? Is it comparing char** and char*?
UPD:
Function that's loading the dictElem
void readd(FILE *file){
int i=0,size=0; /* local size */
char line[1024]; /* Local array for a single word read */
printf("Loadingn dict...\n");
while ((fgets(line,sizeof(line),file))!=NULL){
dictElem=(char**)realloc(dictElem,(size+1)*sizeof(char *));
dictElem[size++]=strdup(line);
}
printf("Total elements loaded: %d\n",size);
}
Function that reads a user file is very similar, just a little different format.
The problem with your code is in this line if ((cond=strcmp(dictElem[pos],val) == 0)). This line of code assigns the result of expression strcmp(dictElem[pos], val) == 0 to the variable cond, and then checks whether cond is zero or not.
I guess your original intent was to store in cond the result of strcmp, so you should move the closing parenthesis before ==. The correct line is if ((cond = strcmp(dictElem[pos], val) == 0).
There are some other problems with your code:
0 is used as special not-found value, but in the same time 0 can be
returned when element is found at index 0.
Using char *val, when
it is better to use const char *val, because contents of this
string aren't going to be modified. It is always better to write const-correct code.
Your problem is this line:
if ((cond=strcmp(dictElem[pos],val) == 0))
The parentheses are giving it the wrong order of evaluation and cond will always end up 0 or 1 (because you're assigning the results of the comparison strcmp() == 0 to it). Try this instead:
if ((cond=strcmp(dictElem[pos],val)) == 0)

Resources