Binary search in C language [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
What is the problem with the next code ?
It is a code for making a binary search between the elements of an array that we fill randomly using the rand() function. We use here the function bin_sear to sort and return for us a boolean value true if the element we seek is found in our table and flase if the element we dont find doesent figure in our table. The code doesent work. So where is the error here ?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum { false, true } bool;
bool bin_sear(int k[] ,int s , int target );
int main()
{
int a[10];
int i,j;
char k;
bool bin;
while(1){
srand(time(NULL));
// we fill our table
for(i=0;i<10;i++){
a[i]=rand()%101+1;
}
printf("Please enter the element you are seeking for: ");
scanf("%d",&j);
if(bin_sear(a[10],10,j)==true){
printf("The element you seek exists in our array");
}
else {
printf("The element you are seeking doesent exist in our array");
}
if (k=='n'){
break;
}
}
return 0;
}
bool bin_sear(int k[],int s, int target){
int i,j,pos,aux,low,high,test;
for (i=0;i<s;i++){
pos=i;
for (j=i;j<s;j++){
if (k[j]<pos){
pos=j;
}
aux=k[pos];
k[pos]=k[i];
k[i]=aux;
}
}
low=0;
high=s;
while (low<high-1){
test=(low+high)/2;
if (target<k[test]){
high=test;
}
else low=test;
}
if (target==k[test]){
return true;
}
else return false;
}

A number of errors in your code.
You need to call bin_sear with the pointer to the array, not element a[10] (which will give you an immediate segmentation fault):
if(bin_sear(a[10],10,j)==true){
should be
if(bin_sear(a,10,j)==true){
Next - take a look at your bubble sort routine. You have the indices wrong, and the braces in the wrong place, and you are comparing a value to an index with your if statement. Modify it to this, and you will get a sorted array:
for (i=0;i<s-1;i++){
pos=i;
for (j=i+1;j<s;j++){
if (k[j]<k[i]){
pos=j;
aux=k[pos];
k[pos]=k[i];
k[i]=aux;
}
}
}
Next, you don't seem to set the value of k anywhere, so you have an infinite loop. Fix all that, and things will work a little bit better. Recommend you put a lot of printf statements in your code if this is not enough (and use a smaller range of random numbers initially to improve your chances of a hit).
Working code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum { false, true } bool;
bool bin_sear(int k[] ,int s , int target );
int main()
{
int a[10];
int i,j;
char k;
bool bin;
while(1){
srand(time(NULL));
// we fill our table
for(i=0;i<10;i++){
a[i]=rand()%10+1;
}
printf("Please enter the element you are seeking for: \n");
// scanf("%d", &j); // not scanning input since this is codepad
j = 5;
printf("you entered: %d\n", j);
fflush(stdout);
if(bin_sear(a,10,j)==true){
printf("The element [%d] exists in our array\n", j);
}
else {
printf("The element [%d] doesn't exist in our array\n", j);
printf("The array contains:\n");
for(i = 0; i < 9; i++) printf("%d, ", a[i]);
printf("%d\n", a[9]);
}
printf("Would you like to test for another element?\n");
// k = getchar();
k = 'N'; // simulating user pressing uppercase N
if(tolower(k) == 'n') {
printf("goodbye!\n");
break; // do this only once
}
}
return 0;
}
bool bin_sear(int k[],int s, int target){
int i,j,pos,aux,low,high,test;
printf("starting to sort\n");
fflush(stdout);
for (i=0;i<s-1;i++){
pos=i;
for (j=i+1;j<s;j++){
if (k[j]<k[i]){
printf("swapping %d and %d\n", i, j); fflush(stdout);
pos=j;
aux=k[pos];
k[pos]=k[i];
k[i]=aux;
}
}
}
printf("sort finished\n");
printf("elements now:\n");
for(i = 0; i < s; i++) printf("k[%d] = %d\n", i, k[i]);
fflush(stdout);
low=0;
high=s;
while (low<high-1){
test=(low+high)/2;
if (target<k[test]){
high=test;
}
else low=test;
}
if (target==k[test]){
return true;
}
else return false;
}

if(bin_sear(a[10],10,j)==true){ => if(bin_sea(a, 10, j) == true) from a quick glance. You need to pass the array into the function, a[10] would try to index the eleventh elment of the array, is also the wrong type (being an int instead of an array), and will probably cause an access violation exception, because the array is only ten elements long. Lots of errors for four characters, eh?

It makes no sense to write a function which sorts the array and then makes the binary search. You should separate the two algorithms, otherwise a linear search would be more efficient.

Related

making a staircase of x's using loops in C, but I keep getting squares

So I need to make a staircase but I clearly have something wrong with my logic. Any advice on how to approach this? I only end up getting squares.
#include <stdio.h>
int main()
{
int a,b,z,y,p;
char x;
scanf("%i ", &a);
printf("Number of stairs is: %i\n", a);
printf("up: \n");
for(b=0; b<a; b++) {
for(z=1; a>=z; z++) {
x='x';
p=1;
if ((p=z)) {
printf("%c", x);
}
else {
printf(" ");
}
p++;
}
printf("\n");
}
}
Your code has many flaws and lack of clarity is one of them. Nevertheless, the reason you have a square is because p=z is always true (setting the value of p to z returns the value of z and this, in your code is always 1 or higher - a true value for C standards).
Here is a code that works, loosely based on your example:
#include <stdio.h>
int main() {
int numberSteps,currentStep,currentColumn;
scanf("%i", &numberSteps);
printf("Number of stairs is: %i\n", numberSteps);
printf("up: \n");
for(currentStep=0; currentStep<numberSteps; currentStep++) {
for(currentColumn=0; currentStep>=currentColumn; currentColumn++) {
printf("x");
}
printf("\n");
}
}
Please notice that I changed the variable names so that they became meaningful and also got rid of the unnecessary variables and the unnecessary test if ((p=z)) that was cluttering your code.

the program is running on code blocks and after it stops [closed]

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 8 years ago.
Improve this question
#include <stdio.h>
#include <stdlib.h>
#define N 10
float func ( int *arr, int n, int *count )
{
int *p,i;
float sum=0;
p=arr;
for (i=0;i<n;i++)
{
sum += *p;
p++;
}
sum /= n;
count=0;
p=arr;
for(i=0;i<n;i++) //לולאה שעוברת על כל המערך ומוסיפה כל תוכן של איברבמערך שיותר גדול מהממוצע
{
*count+= (*p>sum);
p++;
}
return sum;
}
void main()
{
int i, count=0, arr[N]={0}, n=N;
for(i=0;i<N;i++)
{
printf("Please enter your grade\n");
scanf("%d",&arr[i]);
}
for(i=0;i<N;i++)
printf("%d ",arr[i]);
printf("The average in class is: %f and the number of students that had the best grades(MORE) are: %d \n",func(arr,n,count),count);
}
I need some help on this program.
the code is above,
the program need to get from the users 10 grades and then print average and count how many grades is more then the average
Your main function is incorrectly declared. You should compile with all warnings and debug info (e.g. gcc -Wall -g if using GCC, which is probably used by your Codeblocks IDE...) then you should use the debugger (e.g. gdb). And you should test the result of scanf(3)
BTW,
count = 0; // better written as count = NULL;
is wrong: it is clearing the pointer. You probably want
*count = 0;
Also, your last printf is supposing some order of evaluation (since you expect the call to func to change count before printing count), so is undefined behavior. You need:
float avg = func(arr,n,&count);
// from http://stackoverflow.com/a/25382154/841108
printf("The average in class is: %f and the number"
" of students that had the best grades are: %d \n",
avg,count);
Plese show or tell your teacher that you got help on SO (he will find out anyway)
BTW, I can't understand why students are asking their homework on the web. They don't learn anything by doing that, and their teacher will notice anyway.
You are calculating sum and count in func, so you can't return two values at a time. so count the marks which are greater then average in main().
Try this-
#include <stdio.h>
#include <stdlib.h>
#define N 10
float func ( int *arr, int n)
{
int *p,i;
float sum=0;
p=arr;
for (i=0;i<n;i++)
{
sum += *p;
p++;
}
sum /= n;
printf("%lf \n",sum);
return sum;
}
int countfun(int *arr, float sum)
{
int i,count = 0;
for(i=0;i<N;i++)
{
if(arr[i] > sum)
count++;
}
return count;
}
void main()
{
int i, count=0, arr[N]={0}, n=N;
float sum=0;
for(i=0;i<N;i++)
{
printf("Please enter your grade\n");
scanf("%d",&arr[i]);
}
for(i=0;i<N;i++)
printf("%d ",arr[i]);
sum = func(arr,n);
count = countfun(arr,sum);
printf("The average in class is: %f and the number of students that had the best grades(MORE) are: %d \n",sum,count);
}
You can use a getchar() just after the last printf() to wait for a character.
You think that the execution window closes without printing. That is wrong. It does print and then exits before you can even see the output.
P:S - You have some problems with your code as mentioned in the rest of the answers. Fix them and then try this

array that accepts a number only once(code doesn't work) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I need to make an array that accepts each number just once and if the user tries to insert a number more than once,then he must enter an other number...can anyone help me please?
I have tried this so far:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int a[5];
int i,j,num;
scanf("%d",&num);
a[0]=num;
for(i=1;i<5;++i){
again: scanf("%d",&num);
if(a[i]!=a[i-1])
a[i]=num;
else
goto again;
}
for(i=0;i<5;i++)
printf("%4d\n",a[i]);
system("pause");
return 0;
}
but the code just doesn't work and i don't know why
it is observed from your code that given array must be filled but it should not contain redundant values.
following code iterates until the array is filled with no redundant value, once the array is filled it terminates.
int a[5],i=1,k=0,p;
int num;
scanf("%d",&num);
a[0]=num;
while(i<5)
{
scanf("%d",&num);
for(p=0;p<=k;p++)
{
if(a[p]==num)
{
break;
}
if(p==(k))
{
a[i]=num;
k=i;
i++;
}
}
}
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
hope this could help you
You are just comparing the new entered value with the previous one in a[i]!=a[i-1].
You better create a function to test the new value with the entire array, like
int valueExists(int num, int a[], int len) {
int i;
for (i = 0; i < len; i++) {
if (a[i] == num) {
return 1;
}
}
return 0;
}
Make sure you adding the new value to the array only after testing the value is not there.
again: scanf("%d",&num);
if (valueExists(num, a, i)) {
goto again;
} else {
a[i] = num;
}
(The loop you created with the goto can be replaced by a do-while loop, but that is not the issue here)

Program stops and does nothing for no reason [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Here is my code. It will take the info from the user fine, but it doesn't call prims! (it doesn't even print the statement before the call..). The issue is, this main() is simply copy-and-pasted from an attempt at this problem using kruskals instead of prims.. the main is unchanged, and it used to work fine, the only difference is prims() is now there. I can't see any reason why the program would just.. stop (and then does nothing. Blinking cursor nothing). What's going on?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 50
typedef struct graph{
int vertices;
int edges;
int vertex[MAX];
int edge[MAX][4]; /*[i][0]=i (edge ref) [i][1]=vertex1 [i][2]=vertex2 [i][3]=weight*/
} Graph;
void prims(Graph graph);
int main () {
Graph* graph=malloc(sizeof *graph);
printf("Please enter the number of vertices in your graph: ");
scanf("%i", &graph->vertices);
printf("\nPlease enter the number of edges in your graph: ");
scanf("%i", &graph->edges);
for (int i=0; i<graph->edges; ++i) {
graph->edge[i][0]=i;
ensure_valid_input:
printf("\nPlease enter the vertices connected by edge %i, and its weight: ",i+1);
scanf("%i %i %i", &graph->edge[i][1], &graph->edge[i][2], &graph->edge[i][3]);
if (graph->edge[i][1]>graph->vertices || graph->edge[i][2]>graph->vertices || graph->edge[i][1] <= 0 || graph->edge[i][2] <= 0) {
printf("\nERROR: One of these vertices is invalid; ensure they are both in range 1 - %d\n", graph->vertices);
goto ensure_valid_input;
}
}
printf("Try to call the function?");
prims(*graph);
/*Print result to screen*/
/*Print result to file*/
return 0;
}
void prims(Graph graph){
printf("Function called...");
/*Initialise sets and test-values*/
int edges_ordered[graph.edges];
int used_vertices[graph.vertices];
int used_edges[graph.vertices-1];
int least_avail_edge;
int least_edge_reset;
int existing_entry;
int done=1;
int vertex_present;
for (int i=0; i<graph.vertices; ++i) {
if (i=0) {
used_vertices[i]=0;
}
else {
used_vertices[i]=-1;
}
}
/*Order the edges*/
for (int i=0; i<graph.edges; ++i) {
least_avail_edge = least_edge_reset;
existing_entry = 1;
for (int j=0; j<graph.edges; ++j) {
if (graph.edge[j][3]<=graph.edge[least_avail_edge][3]) {
for (int k=0; k<graph.edges; ++k) {
if (edges_ordered[k]==graph.edge[j][0]) {
existing_entry=0;
}
}
if (existing_entry==1) {
least_avail_edge=j;
}
}
}
edges_ordered[i]=least_avail_edge;
}
//Diagnotstic Print
for (int i=0; i<graph.edges; ++i) {
printf("\n%d) Edge %d, Weight %d\n)", i+1, edges_ordered[i]+1, graph.edge[i][3]);
}
/*Continually add next appropriate edge to tree until spanning*/
while (done!=0) {
/*Test to see if all vertices are in the tree yet*/
done=0;
for (int i=0; i<graph.vertices; ++i) {
vertex_present=1;
for (int j=0; j<graph.vertices; ++j) {
if (graph.vertex[i]==used_vertices[j]) {
vertex_present=0;
}
}
if (vertex_present==1) {
/*Vertex is missing from tree -- not done!*/
done=1;
break;
}
}
}
}
There are a lot of problems with this code, but I suspect the culprit is inside your prims() function:
if (i=0) {
I think you mean ==. You're setting i to zero each time through the loop, which causes the loop to never terminate, freezing your program.
Other problems are that least_edge_reset is uninitialized, the return value of malloc is not cast (depends on the C/C++ version and compiler settings whether you'll get an error or warning for this), and sizeof *graph is awkward. Also there's no protection against exceeding the maximum number of edges, etc. etc., but I'll stop there since it's not what you were asking about.
I suspect your print statement IS running, but since there is no \n, it is being buffered and not displayed on screen right away, and never gets displayed because prims() is stuck in an infinite loop.

Prime Number Check 1-100 (C) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
The code below is to read input from the user to check if an int [1-100] is a prime number or not. (If out of range, will print "Done). If non prime, will output that to the console and the number divisible.
Right now this program is running correctly for 1-10 except for 3 and 9... Any suggestions?
#include <stdio.h>
int main()
{
int num, i;
printf("Number [1-100]:? \n");
scanf("%d", &num);
while(num>0 && num <101)
{
if (num==1||num==2)
printf("Prime\n");
for (i=2; i<=num/2; ++i)
{
if (num%i==0)
{
printf("Non-prime,divisible by %d\n",i);
break;
}
else {
printf("Prime\n");
break;
}
}
printf("Number[1-100]:? \n");
scanf("%d",&num);
}
printf("Done\n");
}
First, make sure your code has appropriate whitespace. This will help you realize when things aren't lined up like you think they are.
#include <stdio.h>
int main()
{
int num, i;
printf("Number [1-100]:? \n");
scanf("%d", &num);
while(num>0 && num <101){
if (num==1||num==2)
printf("Prime\n");
for(i=2; i<=num/2; ++i)
{
if (num%i==0)
{
printf("Non-prime,divisible by %d\n",i);
break;
}
else {
printf("Prime\n");
break;
}
}
printf("Number[1-100]:? \n");
scanf("%d",&num);
}
printf("Done\n");
}
Now you should realize that your else statement happens on the first check! So when 3 is not divisible by 2, it prints "prime."
And then it breaks out of the loop.
And this happens for EVERY number. All your program is doing is checking to see if numbers are divisible by 2.
If you wrote "Odd" instead of "Prime" it would at least be correct there.
This is the kind of problem where setting a flag might be useful (there are other ways to do this, but this is one way).
So you could set a flag, say int isPrime = 1;
Now, if you find out that the number is not prime, you simply set isPrime = 0;.
Finally, at the end of the for loop (let me repeat: AFTER the for loop finishes), you need to check that variable.
And you can say,
if (isPrime == 1)
{
printf("Prime\n");
} else
{
printf("Non-prime.");
}
I'll let you figure out how to print the divisor :)
(For reference, correctly using the flag would look like this -- and for clarity I removed the 'feature' in which it continuously looped)
#include <stdio.h>
int main()
{
int num, i;
int isPrime = 1;
printf("Number [1-100]:? \n");
scanf("%d", &num);
for(i=2; i<=num/2; ++i)
{
if (num%i==0)
{
isPrime = 0;
break;
}
}
if (isPrime == 1)
{
printf("Prime\n");
} else
{
printf("Non-prime.");
}
printf("Done\n");
}
The reason why 3 is behaving differently is that the for logic never reaches 3. For "(i=2; i <= num/2; ++i)", if num equals 3, then the i (being 2) is no longer less than 3/2, which is 1 (after rounding off). So, you should add "num==3" check to the "if (num==1||num==2)".
You're not checking the entire range between 2 and num/2. You need a while loop and a prime flag.
Something like this.
while(num>0 && num <101)
{
unsigned char prime = 1; // set prime flag
i = 2;
while( i < (num/2)+1)
{
if(num%i == 0)
prime = 0;
i++;
}
if(num == 1)
prime = 0;
if(prime == 0)
printf("%d is nonprime\n", num);
else
printf("%d is prime\n", num);
prime = 1;
printf("Number[1-100]:? \n");
scanf("%d",&num);
}

Resources