my binary search function doesn't work properly - c

1st of all, sorry my english, it's not my mother language.
Hello everyone, I'm having a problem with my binary search function. I need to make a recursive function(using C language) of binary search, using the boolean type, here it is:
bool binary_search(int x, int array[], int m, int n){
int middle=(m+n)/2;
if(m>n) return(0);
else if(x == array[middle]) return(1);
else if(x < array[middle]) return(binary_search(x, array, m, middle-1));
else return(binary_search(x, array, middle+1, n));
}
here is the call in the main function:
printf("type the element to search: \n"); scanf("%d", &x);
if(binary_search(x, A, 0,dim-1)) printf("Found!\n");
else printf("Not found!\n");
The problem is, it always return "not found" even if the element is not in the array. I tried to change the logic inside the if command, but it just made all results become "found". If anyone can help, I'll be glad.
UPDATED: I changed the "=" problem, but the output still wrong, I printed the output of the function, and it's always zero

The following line has a serious problem:
else if(x = array[middle]) return(1);
Instead of comparing x to array[middle], you are assigning the value of array[middle] to x. Provided this value is nonzero, it will always evaluate to true, and so your function will always return at that point. You should use ==, which compares for equality, instead of =, which means assignment.
This is an extremely common error among beginning C programmers, so you may wonder why A = B is even an expression at all in C, rather than a statement like in Python. The (ex post facto?) rationale is that it is sometimes very convenient to be able to assign a variable inside an expression. Consider:
char *error;
if ((error = do_something()) != NULL) {
printf("error: %s\n", error);
// ...
}

You are using assignment = rather than the test for equality ==. The resulting expression is probably non-zero so the if compares as true.

Ok did u check if u give sorted array as an input to your binary search function? if it is not then using binary search will not give you the correct answer.

I founded the error:
I generate random numbers in a function("random_numbers()"), and the "dim" variable is inside that function, so, the dim inside the main() is 0. so the return value of the search will always be 0. I'm feeling a little bit stupid, but thanks all for the help. Sorry by the newbie error.

Related

Searching for all integers that occure twice in a vector

I got the task in university to realize an input of a maximum of 10 integers, which shall be stored in a one dimensional vector. Afterwards, every integer of the vector needs to be displayed on the display (via printf).
However, I don't know how to check the vector for each number. I thought something along the lines of letting the pointer of the vector run from 0 to 9 and comparing the value of each element with all elements again, but I am sure there is a much smarter way. I don't in any case know how to code this idea since I am new to C.
Here is what I have tried:
#include <stdio.h>
int main(void)
{
int vector[10];
int a;
int b;
int c;
a = 0;
b = 0;
c = 0;
printf("Please input 10 integers.\n\n");
while (a <= 10);
{
for (scanf_s("%lf", &vektor[a]) == 0)
{
printf("This is not an integer. Please try again.\n");
fflush(stdin);
}
a++;
}
for (b <= 10);
{
if (vector[b] != vector[c]);
{
printf("&d", vector[b]);
c++;
}
b++;
}
return 0;
}
Your code has several problems, some syntactic and some semantic. Your compiler will help with many of the former kind, such as
misspelling of variable name vector in one place (though perhaps this was a missed after-the-fact edit), and
incorrect syntax for a for loop
Some compilers will notice that your scanf format is mismatched with the corresponding argument. Also, you might even get a warning that clues you in to the semicolons that are erroneously placed between your loop headers and their intended bodies. I don't know any compiler that would warn you that bad input will cause your input loop to spin indefinitely, however.
But I guess the most significant issue is that the details of your approach to printing only non-duplicate elements simply will not serve. For this purpose, I recommend figuring out how to describe in words how the computer (or a person) should solve the problem before trying to write C code to implement it. These are really two different exercises, especially for someone whose familiarity with C is limited. You can reason about the prose description without being bogged down and distracted by C syntax.
For example, here are some words that might suit:
Consider each element, E, of the array in turn, from first to last.
Check all the elements preceding E in the array for one that contains the same value.
If none of the elements before E contains the same value as E then E contains the first appearance of its value, so print it. Otherwise, E's value was already printed when some previous element was processed, so do not print it again.
Consider the next E, if any (go back to step 1).

Variable Initialization in Function

I'm fairly new to coding and am currently learning C. In my C programming class, my instructor gave us the assignment of writing a program that uses a function which inputs five integers and prints the largest. The program is fairly simple even for me, but I'm facing some problems and was hoping to get some advice.
#include <stdio.h>
int largest(int x);
int main(void) {
int integer1;
largest(integer1);
return 0;
}
int largest(int x) {
int i;
for (i = 0; i < 5; i++) {
printf("Enter an integer: ");
scanf_s("%d", &x);
}
return x;
}
This is the code that I have written. The main problem that I am having is that in my main method, the IDE tells me to initialize the value of integer1. However, I'm not really sure how to do that because I'm supposed to input the value within the largest() method via the scanf_s function. How may I solve this?
The problem is here, the warning message is to warn you about the potential pitfall of using the value of an uninitialized automatic local variable. You made the call like
largest(integer1);
but you ignore the return value, so the integer1 remains uninitialized.
Remember, in view of largest(), x is a local copy of the actual argument passed to that function, any changes made to x won't be reflecting to the caller.
That said, your code is nowhere near your requirement, sorry to say. A brief idea to get there would be
Create a function.
Create a variable (say, result) and initialize with minimum possible integer value, INT_MIN
Loop over 5 times, take user input, compare to the result value, if entered value found greater, store that into result, continue otherwise.
return result.
I know that normally help for assignments shouldn't be given but I have to say that you might need to rethink what you want to do.
You are inputting an integer to the function named largest. But why are you only inputting a single integer to a function that should return the largest value. You can't do much with a single number in that case.
You should instead be inputting say an array of 5 values(as said in your assignment) to the function and let it return the largest.
The order would then be:
Read 5 values and save to an array
Call the function largest with the array as input
Let the function do it's work and return the largest value
Do what ever you want with the largest value
But if you only want to remove the warning simply type
int integer1 = 0;

Can anybody explain the error in the program i made, can anybody why i didn't workout?

how is your day :),
Take a look at the below program, the program written below is to calculate the sum of first n natural numbers, the problem is that i get the sum of n-1 natural numbers, can anybody explain why ?
and can anybody also explain why a-- instead of --a.
#include<stdio.h>
main()
{
int a,sum;
printf("Enter a number.");
scanf("%d",&a);
sum=sumnat(a);
printf("Sum of the first %d natural numbers is %d.",a,sum);
}
sumnat(a)
{
int b;
if(a==0)
{
return 0;
}
else
{
b=a+sumnat(--a);
return(b);
}
}
There were several errors, the greatest of which was undefined behaviour in the expression which uses a and also a modified value of a. You should also define your function properly, not rely on default values provided by the compiler.
#include <stdio.h>
int sumnat(int a); // function prototype
int main(void) // correct signature
{
int a, sum;
printf("Enter a number. ");
scanf("%d", &a);
sum = sumnat(a);
printf("Sum of the first %d natural numbers is %d.", a, sum);
return 0;
}
int sumnat(int a) // function has a return type and argument type
{
if(a == 0)
{
return 0;
}
return a + sumnat(a - 1); // there was no need to decrement `a`
}
Program session
Enter a number. 5
Sum of the first 5 natural numbers is 15.
Your program works for me, using gcc on Mac OSX. However, it will not work everywhere, because of this line:
b=a+sumnat(--a);
--a decrements a, but if it does so before the addition, then your result will be wrong. I'm not sure C is required to evaluate expressions strictly left-to-right (I don't think it is). At any rate, since you don't use a after that line, you could fix things this way:
b=a+sumnat(a-1);
As #self says, you should fix the program to handle negative values, and it would be a good idea to consider what is the largest natural number whose sum you can compute this way (and why that is).
There is a difference between them. One first subracts from a and than goes in the function while the other frist goes in... so it never gets subracted and you go to inifinit stack.
"and can anybody also explain why a-- instead of --a"
When you use the prefix operator --a the decrease is done before anything else, while the postfix operator a-- happens after the rest of the expression is resolved, so, lets say, while debugging your code, in a particular moment, a = 5
since the line
b=a+sumnat(--a);
is using the prefix version of the operator, the decrement would happen immediately, making a=4 and then the function sumnat would be called with argument 4
b=a+sumnat(a--);
in this case the postfix operator is being used, so first the function sumnat would be called with the argument 5, since that is the value of a in that moment, then, only when the function returns a value (which would never happen in your example, since it would be called multiple times with the same value, never reaching 0) the decrement would happen

C recursion does not recurse

My search did not yield any results. Also, my english is pretty bad, sorry for that.
So my program should do this:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
float rec();
int main()
{
setlocale(LC_ALL,"");
int w;
scanf("%d",&w);
printf("%f",rec(w));
return 0;
}
float rec(n)
{
if (n<1)
{
printf("Error");
}
else if (n==1)
{
return 6;
}
else if (n>1)
{
return 1/2*rec(n-1)+4;
}
return 0;
}
When the input is 1 it outputs 6, as it is supposed to.
When the input is <1 it outputs "Error0,000000".
When the input is >1 it only outputs the number that is added in
return 1/2*rec(n-1)+4;
In this case, it outputs 4. Why? Is rec(n-1) == 0?
My questions are:
Why won't it work?
How do i make it output "Error" instead of "Error0,000000" when the input is <1?
Integer division!
Here,
return 1/2*rec(n-1)+4;
1/2 will yields 0 due to integer division. So it's always going to be 4 as the final result.
Instead you can do:
return 1.0/2*rec(n-1)+4;
which will make sure the computation happens as double.
You might also simply want to add return 0; in the if (n<1) case and change the function definitio to:
float rec(int n) {... }
If you don't specify a type for n, it defaults to int in pre-C99. But this is no longer the case in C99 and C11.
The problem is mainly a type issue: try
return 1.0/2.0*rec(n-1)+4
to tell the compiler, that you want floating point arithmetic during the calculation. Otherwise, an integer division is performed and casted to float afterwards.
Fwiw: You wouldn't use a recursion for this, an iteration would fully suffice, be better understandable, perform better and needed less resources than the recursive version in c.
I would like to give you the answer of the second question.
You need a buffer for the return value of rec.
So,
float answer = rec(w);
if (NOTHING_HAPPENED)
print("%f", answer);
This will work!
In the case where n<1, you printf "Error" from the called routine, and then return 0 to be printf'd (as a float) in main. Don't do that ;-)
Personally, I'd check for the original being <1 in main as an alternative to calling rec() and printf.
This would be easier to answer if you'd tell us what it's supposed to produce.
However, I suspect your problem is related to rec() taking an integer argument, but returning a float. If you want recursive functions to behave sanely, their argument and return type should match. Quite likely your issue is that at some point you pass a decimal fraction that is approximately equal to 1, which does not get converted to 1 by the implicit type conversion.

C - compare read in float to zero

In my programm I have several float variables that I need to compare to 0. Those variables are being read in through printf.
float a;
scanf("%f", &a);
if (a=0)
{
printf("a is zero");
return 0;
}
But it doesn't work when I give in a 0 through scanf. "a is zero" isn't displayed. It doesn't work with (a=0.0) and doesnt work with (a=0.0f) or (a=0.). The only way I managed to do it is with (0 < a && a < 0.0000000000001)
but I feel like this is not a very good way to do it.
What did I do wrong? Why doesn't it recognize the 0 I input in with scanf as 0?
Just change "=" to "==". You can write "if" statement to following style:
if (CONSTANT == variable)
Change the assignment operator(=) to Comaparison Operator (==) in if Condition.
In addition to that do type casting while comparing the value
if (a==(float)0)

Resources