Binary search not returning the position - c

this code is used to create an array filled with 10 random integers. It sorts the array and then inputs the array into a binary search function. I do not get the position of where my search key is positioned.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int binary_search(int array[], int search, int strt, int ending)
{
int middle;
middle = (strt + ending)/2;//splitting the array in half to compare the search key
if (search > array[middle]){binary_search(array, search, middle + 1, ending);}
else if(search == array[middle])
{
printf("Your search key is indicated in %d position the array Ferrari\n", middle + 1);
return middle;
}
else{binary_search(array, search, strt, middle -1);}
return -1;
}
int main()
{
srand(time(NULL));//random number seed generator
int Ferrari[10];
int size = 10;
int selection;
int temporary = 0;//I'm using this variable to store
//the value returned from linear_search()
int start = 0;
int end;
int i;
//this is to generate a random number between 0 and 101
for(int i=0; i<10; i++) {Ferrari[i] = rand() % 100 + 1;}
//printing the initial array
printf("\nThe array Ferrari consists of -> ");
for(int i=0; i<10; i++){printf("%d, ", Ferrari[i]);}
//--------------------------SORTING--------------------------------------------
for(int f = 0; f < (size - 1); f++)
{
for(int kk = 0; kk < (size - 1 - f); kk++)
{
if(Ferrari[kk] > Ferrari[kk +1])
{
int Te_mP;
Te_mP = Ferrari[kk + 1];
Ferrari[kk+1] = Ferrari[kk];
Ferrari[kk] = Te_mP;
}
}
}
//----------------------------------------------------------------------------
//printing the array after it has been sorted
printf("\n");
printf("\nThe sorted array Ferrari consists of -> ");
for(int i=0; i<10; i++){printf("%d, ", Ferrari[i]);}
start = 0;
end = i -1;
//this will be used to implement the searching algorithm
printf("\n\n");
printf("Please enter a number to test if it is included in the array or not\n");
scanf("%d", &selection);
temporary = binary_search(Ferrari, selection, start, end);
return 0;
}
I keep getting the answer that the search key is positioned in ``0 of array Ferrari. How do I resolve this?
Please let me know what I'm doing wrong over here. Much appreciated.

Look at this line
end = i - 1;
Where is i initialized?
In your loop you have
for(int i=0........
Note by giving int i=0 it means you are creating a new variable i within the for block. So this doesn't alter your original i variable declared at the top. Try using end = size - 1 or it's a best practice to define a constant for this purpose.
#define ARR_SIZE 10
in loop
for(i=0; i<ARR_SIZE;i++)
Then initialize end = ARR_SIZE -1;
And one more thing in your binary_search function is that you don't handle the case when the key is not present in the array.
Something like
if(end==start && array[end] != search)
return -1;
This checks when the search space has only one element and that is not your search element, it means it doesn't exist so we return -1.
Hope this helps

The problem is occurring because you are using uninitialised variable i here:
end = i -1;
Note that the scope of variable i declared in loop init clause is different from the scope of variable i declared in function block.
for(int i=0; i<10; i++){
^^^^^^^
// The scope of i declared in loop init clause is limited to the loop.
To fix the problem, you can use the i declared at function block scope as the loop variable, like this
for(i=0; i<10; i++){
Now, after the loop finishes, the variable i will hold its last value until it's value explicitly modify. But using i to identify the size of array down the code may cause several problems as it is not tightly coupled with the size of array and i may be get modified by other part of code. So, it is not the right idea to use i to identify the size of array.
Since, you are having a variable size which hold the size of array Ferrari, you can do:
end = size - 1;
No need to have another variable to keep the track of size of array. The problem with this is that you have to keep updating the size whenever you change the array size. An alternative of this would be to use a macro to define the array size.
The most appropriate way to set the end of array would be:
end = (sizeof(Ferrari) / sizeof(Ferrari[0])) - 1;

Related

Unexpected output of a growing dynamic array

I am attempting to create a dynamic array that will grow in size if needed, as I don't know how large the array will actually be. My code seems to work until the 8th element of the array where I start to see very large incorrect values that I did not enter. Not sure why this is happening.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv)
{
int val;
int userInput;
int* arr;
int size = 1;
int arrIndex = 0;
arr = (int*) malloc(sizeof(int) * size);
/* prompt the user for input */
printf ("Enter in a list of numbers to be stored in a dynamic array.\n");
printf ("End the list with the terminal value of -999\n");
/* loop until the user enters -999 */
scanf ("%d", &val);
while (val != -999)
{
if (arrIndex >= size)
{
size++;
}
arr[arrIndex] = val;
arrIndex++;
/* get next value */
scanf("%d", &val);
}
int j = 0;
for(j = 0; j < size ; j++)
{
printf("%d \t", arr[j]);
}
}
The size of the array remains 1 and doesn't increase while incrementing size variable.
Your code worked until 8th element because adjacent memory after the array upto 7th element must be free.
In C array index out of bound is not checked and it is programmers responibility.
if you want to increase or decrease size of array you can use realloc inside while loop:
arr=(int*)realloc(arr,sizeof(int)*size);
Also Correct this if condition in your code initially arrayindex is 0 and size is 1 which results in false.
if (arrIndex >= size)
{
size++;
}

Arduino C Multi dimensional array switching

Im stuck with a piece of my Arduino code
Basically I have a multi dimensional array in which every index will store a random letter. But after a small time (eg. 900 milliseconds) every value in the index will move up to the index above it. Ofcourse when the index reaches e.g. [9][0] it will go to the largest index like [9][9]
E.g.: myArray[9][8] contains "K" and myArray[9][7] contains "L"
The "K" in myArray[9][8] will be put in myArray[9][7] and the "L" in myArray[9][7] will go to myArray[9][6] etc. etc
But I have no clue how to do this in C...
myArray[9][8] = myArray[9][7] obviously wouldnt work
There is not problem with assignment, but you must save the element you are writing over first.
In this example all the rewritten values are kept in the last slot of every row, this is just an example- not the only way to go, if you need to move the letters across the rows as well the idea is similar.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void moveLettersInRow(char sArr[][3], int row)
{
int i = 0;
int j = 0;
char temp ;
for (i = 0; i < row; ++i)
{
for(j = 2 ;j > 0;--j)
{
temp = sArr[i][j-1]; /*save the value to be rewritten */
sArr[i][j-1]= sArr[i][2]; /* set the last val in its new place*/
sArr[i][2]= temp; /* set the last elem to the latest rewritten value*/
}
}
}
void printArr(char arr[][3], int size)
{
int i = 0, j= 0;
for(i = 0; i< size; ++i)
{
for(j = 0; j< 3; ++j)
{
printf("%c | ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
char arr[2][3]= {{'a','b','c'},{'a','b','c'}};
moveLettersInRow(arr, 2);
printArr(arr, 2);
return 0;
}
There are several ways to go about this. One would be to use a temporary variable while copying, as Kami Cuk and Fred pointed out.
Another way, which would avoid copying the values, would be to index the array using a modulo operation while reading the array.
myArray[9][(index + offset) % numberOfElementsInArray]
index and offset should both be positive integers.
numberOfElementsInArray is the number of elements in myArray[9]
To get a -1 offset with a positive integer, set offset to numberOfElementsInArray - 1

Correctly passing an array from a function

I have some code to generate an array of size [user_input] in a function called array_generator, using size of array from scanf in main(), and then filling it with the numbers 0 to user_input (0, 1, 2, 3, if user input is 4). The array fills correctly as printf prints
`The array contains the value 1`
`The array contains the value 2`
`The array contains the value 3`, etc.
However when I pass the array to main and printf the array values I get equal statements filled with garbage numbers. I'm also 90% sure I have been passing the arrays and pointers incorrectly (new to them).
The code is below:
#include <stdio.h>
int *array_generator(int number_songs);
int main(void)
{
int input;
int *p;
int i;
int x;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
p = array_generator(input);
x = *p;
for (i = 0; i < input; i++)
{
printf("The array contains the values %d\n", x);
}
return 0;
}
int *array_generator(int n)
{
int a[n];
int *p;
int i;
for (i = 0; i < n; i++)
{
a[i] = i;
printf("The array contains the values %d\n", i);
}
return p = &a[n];
}
One simple solution is to define an array which is bigger than the largest list of songs reasonably possible. For example, since you print every entry, more than a few hundred are not reasonable. On a modern computer space is abundant. You would have a define for the max size on top of the prog, or later in some header:
#define MAX_SONGLIST_LEN 1000
The array can be global, or it can be static inside the function. Let's make it static because you want the function to return the address.
The change is minimal. Just say
static int a[MAX_SONGLIST_LEN];
You may want to change the loop and check for the max length as well:
for (i = 0; i < input && i < MAX_SONGLIST_LEN; i++)
inside array_generator() and main(). You also may want to inform your users about the maximum, and catch numbers which are too large. (You don't do any error handling of user input anyway -- what happens if the user enters a letter instead of a number? Look into the return value of scanf().)
The static array's life time is the lifetime of the program. It will be initialized to all zeroes by the way. If you want to randomly initialize it look at the rand() function.
You are correct in that you are using pointers wrong. The code below preforms the function that you want...
#include <stdio.h>
void array_generator(int n, int arr[]) {
for (int i = 0; i < n; i++) {
arr[i] = i;//array values
//printf("The array contains the values %d\n", i);
}
}
int main() {
int input;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
int array[input];//declare array with length of input
array_generator(input, array);
for(int i=0; i<sizeof(array)/sizeof(array[0]); i++) {//input could also be used at the limit to the for loop
printf("%d", array[i]);
}
printf("\n");
return 0;
}
What you are doing is you are over complicating your code. The first thing you do is you create a function and try to make it return an array. This is not necessary. All you need to do is pass a pointer to the array and all edits to the array will be made on the same scope as the array was declared on.
You also mentioned that you want to find the size of an array. This can be done with array *a of any type and sizeof(a)/sizeof(a[0]). This works by returning the number of bytes used by the array divided by the number of bytes used by the first element in the array.
One more thing that you have that you don't need is x = *p;. when you do this, you are essentially doing this x=*p=array_gen(input);
More information on pointers in C can be found here.

How to count how many times values were used in the array C?

Here's my problem
If certain number has been entered into an array I need that number to be displayed and occurrence of that number in the array.
for example if user enters number 5 three times then "The number 5 has been entered 3 times so far" and so on
Here's my code so far:
int i,j;
int num_count = 0;
for(i=0;i<6;i++) {
num_count = 0;
for(j=1;j<43;j++) {
if( *(num + i) == j) {
printf("The number %d has been used %d times\n",j,num_count);
}//end if
}//end inner for
}//end outer for
I will like to suggest you a very time efficient method for this, but it needs some extra memory.
Assume the upper limit of numbers inside array is 'MAX_NUM_IN_ARRAY',
so you should create array (say counter) of size 'MAX_NUM_IN_ARRAY+1' and initialize it to 0.
int counter[MAX_NUM_IN_ARRAY+1]={0};
now scan the input array from first to last element,
for each number:
//say number is num
counter[num]++;
and at the end you have to just scan that counter array from index 1 to MAX_NUM_IN_ARRAY.
Sample code:
Suppose input array is a[],
number of elements in array is n,
maximum limit of number inside array is MAX_LIMIT
int counter[MAX_LIMIT]={0};
int i;
for(i=0; i<n; i++)
{
counter[a[i]]++;
}
for(i=0; i<MAX_LIMIT; i++)
{
printf("Number %d is appeared for %d times\n", i, counter[i]);
}
============EDIT
You could write a series of functions that handle your collection. the collection could be a 2 dimentional array like so numbers[][] where numbers[n][0] is your number, and numbers[n][1] is the number of times it occurred... and the gold would be in your add() function
add() does a few things, a user passes a value to add(),
first checks if number exists in numbers[n][0]
if the value exists at numbers[n][0]
numbers[n][1]++;
if it doesn't already exist,
check if the array is full
if it is full, copy all the data to a new, larger array
add it to the end of the array.. this is how to do it.
==OR
just design a 1 dimentional array numbers[] that holds all of your numbers.. and the add() function only:
if(it is full){copies to larger array}
adds number to the end;
and modify the code I wrote earlier (Below).. to print the most common number and it's occurrence count
============EDIT
I'm a Java guy so you'll need to translate (shouldn't be too hard..)
This is going to be just like a sorting algorithm with a little bit of extra logic (later search for Selection Sort)
int[] temp = {4,3,2,4,4,5};
////// find the most commonly occuring value
int times;
int moreTimes = 1;
int value = temp[0];
for(int i = 0; i < temp.length; i++) {
times = 1;
for(int j = i+1; j < temp.length; j++) {
if(temp[i] == temp[j])
times++;
}
if(times > moreTimes) {
moreTimes = times;
value = temp[i];
}
}
/////// count the most common value
int count = 0;
for(int i = 0; i < temp.length; i++) {
if(temp[i] == value)
count++;
}
System.out.println("number: " + value + ", count: " + count);

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Resources