Why is my code for binary search not working? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 14 days ago.
Improve this question
The code doesn't print the position of elements at the far left or right positions. I've looked at it for hours please help me find out whats wrong.
type here
#include<stdio.h>
#define max 50
void binarysearch(int l,int r,int key,int num[])
{
int mid=(l+r)/2;
if(num[mid]==key)
{
printf("Element found at location %d",mid+1);return;
}
else if(num[mid]<key)
{
return binarysearch(l,mid-1,key,num);
}
else
{
return binarysearch(mid+1,r,key,num);
}
printf("Element not found ");return;
}
int main()
{
int i,key,size,num[max];
printf("Enter size of array : ");scanf("%d",&size);
for(i=0;i<size;i++)
{
printf("Enter the element : ");scanf("%d",&num[i]);fflush(stdin);
}
printf("Enter key to search : ");scanf("%d",&key);
binarysearch(0,size-1,key,num);
return 0;
}
I'm gonna go insane. Send help

For starters you need to check within the function whether r is not less than l. Without this check the function can invoke undefined behavior.
These if statements are incorrect
else if(num[mid]<key)
{
return binarysearch(l,mid-1,key,num);
}
else
{
return binarysearch(mid+1,r,key,num);
}
For example if num[mid] is less than key then you need to call the function recursively like
return binarysearch(mid+1, r, key,num);
otherwise like
return binarysearch(1, mid-1,key,num);
Pay attention to that the function should not output any message. It should returns to the caller either the index of the found element or for example -1 if the searched value is not found in the array. It is the caller of the function that will decide whether to output a message.
It would be much better to declare the function at least like
int binarysearch( const int num[], int size, int key );
or like
int * binarysearch( const int num[], size_t size, int key );
For the last declaration the function returns a pointer to the found element or NULL.
Here is a demonstration program that shows the function implemengtation.
#include <stdio.h>
int * binarysearch( const int a[], size_t n, int key )
{
if (n == 0)
{
return NULL;
}
else if (a[n / 2] < key)
{
return ( int * )binarysearch( a + n / 2 + 1, n - n / 2 - 1, key );
}
else if ( key < a[n / 2] )
{
return ( int * )binarysearch( a, n / 2, key );
}
else
{
return ( int * )a + n / 2;
}
}
int main( void )
{
int a[] = { 1, 3, 5 };
const size_t N = sizeof( a ) / sizeof( *a );
for (int key = 0; key < a[N - 1] + 2; ++key)
{
int *p = binarysearch( a, N, key );
if (p != NULL)
{
printf( "The value %d is found at position %td.\n", key, p - a );
}
else
{
printf( "The value %d is not found.\n", key );
}
}
}
The program output is
The value 0 is not found.
The value 1 is found at position 0.
The value 2 is not found.
The value 3 is found at position 1.
The value 4 is not found.
The value 5 is found at position 2.
The value 6 is not found.
Pay also attention to that this call in your program
fflush(stdin);
has undefined behavior.

You've simply wrote the code in opposite places.
The right code would be:
#include<stdio.h>
#define max 50
void binarysearch(int l,int r,int key,int num[])
{
int mid=(l+r)/2;
if(num[mid]==key)
{
printf("Element found at location %d",mid+1);return;
}
else if(num[mid]<key)
{
// Wrong Code
// you've done the opposite operation
//return binarysearch(l,mid-1,key,num);
// Correct Code
return binarysearch(mid+1,r,key,num);
}
else
{
// Wrong Code
// same problem as before.. you've done opposite operation
//return binarysearch(mid+1,r,key,num);
// Correct Code
return binarysearch(l,mid-1,key,num);
}
printf("Element not found ");return;
}
int main()
{
int i,key,size,num[max];
printf("Enter size of array : ");scanf("%d",&size);
for(i=0;i<size;i++)
{
printf("Enter the element : ");scanf("%d",&num[i]);fflush(stdin);
}
printf("Enter key to search : ");scanf("%d",&key);
binarysearch(0,size-1,key,num);
return 0;
}
Hope this would help.

There are two problems:
1- Your arguments about the recursive called functions are wrong.
2- The recursive call is infinite.
You should change your binarysearch function to this:
void binarysearch(int l, int r, int key, int num[])
{
int mid=(l+r)/2;
if(l > r)
{
printf("Element not found");
return;
}
if(num[mid] == key)
{
printf("Element found at location %d", mid+1);
return;
}
if(num[mid] < key)
{
return binarysearch(mid+1, r, key, num);
}
return binarysearch(l, mid-1, key, num);
}

Related

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

When I make the line active in the quicksort5 function, it doesn't sort well. But why?

Recently I was studying about quicksort,
I wrote 2 programs: One works successfully, while the other doesn't.
I tried to find why the other one is not working.(I know the reason but I want to know the reason under the reason)
The only difference between 2 programs is a line in quicksort5 function,
which is below:
swap( &list[ ( (backwards-forwards) /2 ) ], &list[last] );
They both includes stdio.h and also have 3 functions which are called main, quicksort5, swap.
The upper lines of the program is below:
#include <stdio.h>
int quicksort5(int *, int, int);
int swap(int *, int *);
1) The main function is below:
int main()
{
int arrayofintegers[4096];
int n=0, quantity=0;
printf("Please enter how many integer numbers you want to get sorted: ");
scanf("%d",&quantity);
if (quantity <= 0)
return -1;
printf("\nPlease give at max 10 digits per number.\n\n");
while ( n<quantity ) //import the numbers
{
printf("the %5d. number = ",n+1);
scanf("%d",&arrayofintegers[n]);
n++;
}
printf("\n");
quicksort5(arrayofintegers, 0, quantity-1);
n=0;
while ( n<quantity ) //The numbers will be displayed.
{
printf("the new %5d. number =%11d\n", n+1, arrayofintegers[n]);
n++;
}
return 0;
}
2) The quicksort5 function is below:
int quicksort5(int *list, int forwards, int backwards)
{
if ( forwards >= backwards )
return 0;
int const first = forwards;
int const last = backwards;
/* //If I make the line bellow active the function doesn't sort successfully. But I want to know the main reason in this.
swap( &list[ ( (backwards-forwards) /2 ) ], &list[last] ); */
int const pivot = list[last];
int isforwardswaiting = 0;
int isbackwardswaiting = 0;
backwards--; // the pivot won't change
while (forwards<backwards)
{
isforwardswaiting = (list[forwards] >= pivot);
isbackwardswaiting = (list[backwards] < pivot);
if(isforwardswaiting && isbackwardswaiting)
{
swap(&list[forwards],&list[backwards]);
forwards++;
backwards--;
}
else
{
if ( !(isforwardswaiting))
forwards++;
if ( !(isbackwardswaiting))
backwards--;
}
}
if (list[forwards] < pivot)
forwards++;
swap(&list[forwards],&list[last]); //placing the pivot
/* list[first], list[first+1] ... list[forwards-2], list[forwards-1] ==> the numbers smaller than the pivot
list[forwards] ==> the number which is the pivot
list[forwards+1], list[forwards+2] ... list[last-1], list[last] ==> the numbers greater than the pivot */
quicksort5(list, first, forwards-1);
quicksort5(list, forwards+1, last);
}
3) The swap function is below:
int swap(int *a, int *b)
{
int c=*a;
*a=*b;
*b=c;
return 0;
}
Thanks in advance for your answers.
You just need to modify the following line in your function quicksort5 :
swap( &list[ ( (backwards-forwards) /2 ) ], &list[last] );
to this:
swap( &list[ (forwards + (backwards-forwards) /2 ) ], &list[last] );
To understand why the first statement causes problem, consider the case when backwards = 6 and forwards = 4.
So, (backwards-forwards) /2 evaluates to 1, and the swap function swaps the element at index 6 with the one at index 1, which is not desired.
Hope it helps!

Function in C not returning proper value

I'm trying to check whether an array is sorted without using a loop. It's working properly, i,e. if I have an array with elements that are in ascending order, the printf executes, since I get "Sorted." But
printf("Array 1 returns: %d \n\n", sortCheck(arr1, SORTED1));
returns 0? Why is this?
Thanks. Here's the entire code.
#include<stdio.h>
const int SORTED1 = 5;
int sortCheck (int arr[], int arrSize);
int indexCounter = 0;
int main()
{
int arr1[] = {1,2,3,4,5};
printf("Array 1: \n");
printf("Array 1 returns: %d \n\n", sortCheck(arr1, SORTED1));
indexCounter = 0;
return 0;
}
int sortCheck(int arr[], int arrSize)
{
if ( (arr[indexCounter]==arr[arrSize-1]) && (indexCounter==arrSize-1) )
{
printf("Sorted. \n");
return 1;
}
if ( arr[indexCounter] <= arr[indexCounter+1] )
{
indexCounter++;
sortCheck(arr, arrSize);
}
else
{
printf("Not sorted.");
return 0;
}
}
You are seeing undefined behavior due to a missing return statement.
if ( arr[indexCounter] <= arr[indexCounter+1] )
{
indexCounter++;
// Problem. Missing return.
sortCheck(arr, arrSize);
}
Change the offending line to:
return sortCheck(arr, arrSize);
Following changes should print value 1
int sortCheck(int arr[], int arrSize)
{
int val = 0;
if ( (arr[indexCounter]==arr[arrSize-1]) && (indexCounter==arrSize-1) )
{
printf("Sorted. \n");
return 1;
}
if ( arr[indexCounter] <= arr[indexCounter+1] )
{
indexCounter++;
val = sortCheck(arr, arrSize);
return val;
}
else
{
printf("Not sorted.");
return 0;
}
}
the sortCheck() function does not check if the array is sorted.
there are two reasons for this.
1) when the recursive call was invoked, the returned value is being ignored, so the information about a particular byte pair is lost.
2) the index (arrSize) is always passed, rather than the offset to the current byte index
I.E. the whole sortCheck() function needs to be re-designed.
Using a debugger (or a printf( of the parameters) in the path that calls the recursive sortCheck() would have revealed that fact.

How will I print the highest scorer (with it's other "struc mates") using a function. C

Beginner in C here, please bear with my question since I am having a hard time explaining it. And I'm really sorry if my terms are incorrect. I hope you get it.
Say that I have my struct like this:
struct studentType
{
char studentFName[20];
char studentLName[20];
int score;
char grade;
}s[20];
and I have inputted 3 elements in to s. Now I have compared each others score,
through this:
void getHighestScorer(struct studentType s[20])
{
int maximum, i;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
}
}
}
and I have found that s[2] has the highest score compared to the others. How will I actually print that one on another function with its other "struc mates"
I actually tried doing it on the function above like this(and it didn't work):
void getHighestScorer(struct studentType s[20])
{
int maximum, i;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
}
}
printf("The highest scorer is: %s, %s %d\n", s[i].studentLName,s[i].studentFName,
s[i].score);
}
My whole program is here
Define the function the following way
int getHighestScorer( struct studentType s[], size_t n )
{
int maximum;
size_t i;
if ( n == 0 ) return 0;
maximum = s[0].score;
for ( i = 1; i < n; i++ )
{
if ( maximum < s[i].score ) maximum = s[i].score;
}
return maximum;
}
and use it like
printf( "Maximum score is %d\n", getHighestScorer( s, 3 ) );
Or another approach
size_t getHighestScorer( struct studentType s[], size_t n )
{
size_t maximum = 0;
size_t i = 1;
for ( ; i < n; i++ )
{
if ( s[maximum] < s[i].score ) maximum = i;
}
return maximum;
}
And use it like
size_t i = getHighestScorer( s, 3 );
printf("The highest scorer is: %s, %s %d\n", s[i].studentLName,s[i].studentFName,
s[i].score);
What you are doing is you are iterating over array till index 3 (i<3) and hence i value at the end of loop would always be 3. So maintain index of last max item.
void getHighestScorer(struct studentType s[20])
{
int maximum, i, index = 0;
maximum = s[0].score;
for(i=1;i<3;i++)//should start with 1 as 0 you are considering is max
{
if (s[i].score > maximum)
{
maximum = s[i].score;
index = i;
}
}
printf("The highest scorer is: %s, %s %d\n", s[index].studentLName,s[index].studentFName,
s[index].score);
}
Hope this is what you are after.
If you want to pass this struct in another function, change this method to return the index and in that method accept your struct and index (that above function would pass) and use your same printf statement that should work.
What do you mean by "struc mates"?
If it means you want to print the other members of the struct along with the score member,
then the following should help:
void printHighestScorer(struct studentType s[20]) //this the function wherein I don't know what to put//
{
int maximum, i;
int maxIndex = 0;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
maxIndex = i;
}
}
printf("The highest scorer is: %s, %s %d\n", s[maxIndex].studentLName,s[maxIndex].studentFName,
s[maxIndex].score);
}
Basically you need to store the index of the struct variable which contains the maximum score.

C- Fix Stack overflow in Recursion

A code in C to find maximum of an array using divide and conquer but it keeps throwing
"stack overflow exception" . Help would be appreciated!
int a[10];
int find(int l,int h)
{
int x;
if(h==0)
{
x=0;
return x;
}
else
{
if(h==1)
{
if(a[0]>a[1])
{
x=0;
return x;
}
else
{
x=1;
return x;
}
}
else
{
int mid,z,y;
mid=(l+h)/2;
y=find(0,mid);
z=find(mid+1,h);
if(a[y]<a[z])
{
x=z;
}
else
{
x=y;
}
return x;
}
}
}
There are only limited variables and I don't see where the function can go into an infinite recursion.
int main()
{
int i,n,max,min,ans;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
ans=find(0,n-1);
printf("the maximum element is- %d\n",ans);
getch();
return 0;
}
Consider the case where you call find(0, 2). Since h > 1, you enter the second else clause, and mid is 1. Then on the second recursive call, it is to find(2, 2). On this recursive call, you again enter the second else, since h is still 2. But the mid is also 2. Now, the first recursive call goes to find(0, 2), which enters an infinite loop.
find(0, 2)
h not 0
h not 1
mid = 1
find(0, 1)
find(2, 2)
h not 0
h not 1
mid = 2
find (0, 2) <-- loop
It seems the intention of the if checks on h is to prevent the mid calculation from being the same as l. If so, then you can calculate the mid variable at the top of your function, and use that as the stopping condition.
It looks like this is an attempt to use divide and conquer to locate the position of the maximum element in the array a. If so, then your first recursive call should restrict itself to the range of [l..mid] instead of going back to 0.
Putting it all together:
int find(int l,int h)
{
int mid = (l+h)/2;
if (mid == l)
{
return (a[l] > a[h]) ? l : h;
}
else
{
int y = find(l, mid);
int z = find(mid+1, h);
return (a[y] > a[z]) ? y : z;
}
}
Here is your code modified, which is running successfully..
The problem is that you weren't checking the difference between l and h but only the value of h...
#include <iostream>
using namespace std;
int a[10];
int find(int l,int h)
{
int x;
if(h-l==0)
{
return h;
}
else
{
if(h-l==1)
{
if(a[l]>a[l+1])
{
return l;
}
else
{
return l+1;
}
}
else
{
int mid,z,y;
mid=(l+h)/2;
y=find(0,mid);
z=find(mid+1,h);
if(a[y]<a[z])
{
x=z;
}
else
{
x=y;
}
return x;
}}}
int main()
{
a[0]=3;
a[1]=7;
a[2]=5;
cout<<find(0,2)<<endl;
return 0;
}
you're using wrong conditions, try:
first if: if(h==l)
second if: if(h-l==1)
third if:
if(a[h]>a[l]) {
return h;
} else {
return l;
}

Resources