Searching an element in an Array using Recursive Function in C Language - c

I am a beginner to arrays in recursion so need some guidance.
I am trying to find whether an element is present in an array or not.
// Program to find whether an element exist in an array or not.
#include <stdio.h>
int arr[5]= {1,2,3,4,5};
int fooSearch(int array1[],int N,int i, int X)
{
if(i==N)
return 0;
else if (array1[i]==X)
return 1;
else
return fooSearch(array1,N,i++,X);
}
// N denotes total size 5
// i counter that moves from 0 to 4 and eliminate recursion when it reaches 5
// X is the element to be found
int main() {
fooSearch(arr,5,0,3);
return 0;
}
The error I obtained is Segmentation Fault (SIGSEGV).
Please guide me what wrong I am doing with this code.

i++ is a post-fix increment, which increments i after the expression containing it is evaluated. Thus, every call to fooSearch effectively becomes to fooSearch(array1, N, 0, X). Recursion is endless, hence the segfault (or a stack-overflow on my compiler). (You can confirm that i is unchanging by placing printf("%d\n", i) at the top of the function.)
Fix this by using pre-fix increments, which increment the variable before evaluation.
return fooSearch(array1, N, ++i, X);
Or use i+1, since you won't be reusing the local variable anyways.
return fooSearch(array1, N, i+1, X);

While calling fooSearch() recursively pass i+1 instead of i++ as post increment i++ doesn't change i in the argument. For e.g
fooSearch(array1,N,i+1,X);

to find whether an element is present in an array or not.
you can initialize number of array elements, Let's say 10 elements:
int num[10]= {2,3,5,6,1,8,4,9,0,7};
Then, Creating for loop for checking if number 9 is not in array then continue until the condition is false then print the element location.
for(i=0; i<10; i++){
if(num[i] != 9){
continue;
}
printf("9 is found here\n%d",i);
break;
}
At the end, You write an if condition to check if the loop is ended and print not found.
if(i==10){
printf("Not Found");
}
The full code is here:
#include <stdio.h>
int num[10]={2,3,5,6,1,8,4,9,0,7};
int i;
int main(void){
for(i=0; i<10; i++){
if(num[i] != 9){
continue;
}
printf("9 is found here\n%d",i);
break;
}
if(i==10){
printf("Not Found");
}
getchar();
return 0;
}

You have to use ++i or i+1 instead of i++.
i++ is a post increment operator, so the value of i that will go to the function will not change.
Just use ++i or i+1 and you will get the answer.

public static boolean checkNumber(int input[], int x) {
int n=input.length;
if(n==0)
return false;
if(input[0]==x)
{
return true;
}
int small[]=new int[n-1];
for(int i=1;i<n;i++)
{
small[i-1]=input[i];
}
return checkNumber(small, x);
}

// Program to find whether an element exist in an array or not.
// Number of elements of array is N, the number to search is X
#include <stdio.h>
int arr[]= {1,2,3,4,5};
int fooSearch(int array1[],int N,int i, int X)
{ if(i==N)
return 0;
else if (array1[i]==X)
return 1;
else
i=i+1;
return fooSearch(array1,N,i,X);
}
int main() {
int x = fooSearch(arr,5,0,9);
printf("%d",x);
return 0;
}

Related

Storing an array in C

Context: I need to write a program that will accept inputs which will be stored into the array. Before storing in to the array, the inputted number must be checked if it already exists in the array or not. If it does not exist, it is stored into the array. If it exists, another input will be asked.
Now, my code will get inputs from the user, but the code will only work for the first input. It won't work for the second until the last input. Any pointers?
This is my code:
#include<stdio.h>
#define size 5
main()
{
int i;
arr[size];
input;
printf("This program will accept ");
printf("unique inputted numbers that will be stored");
printf(" in an array\n");
for(i = 0;i < size;i++)
{
printf("Enter input: ");
scanf("%d",&input);
if (unique(arr,input,i))
arr[i] = input;
else
i--;
//decrement i because ask for input again
}
for(i = 0;i < size;i++)
printf("%d ",arr[i]);
}
int unique(int arr[],int input,int i)
{
int n, z;
n = 0;
z = 1;
while(i > n)
{
if(arr[n] == input)
{
scanf("%d",&n);
z = 0;
break;
}
else
n=1;
break;
}
return z;
}
Your code is wrong at multiple levels:
The logic in the unique function is wrong.
Doing the scanf in the unique function is extremely bad design. The only thing unique should do is return 0 if input is already in the array.
You have used implicit variable declarations here: arr[size]; input;, it should be int arr[size]; int input;.
You should use descriptive variable names which makes your code easier to understand.
This is a working example (explanations in comments).
#include <stdio.h>
#define SIZE 5 // use capitals for macros (this is a convention)
int unique(int arr[], int value, int arrsize)
{
for (int i = 0; i < arrsize; i++)
{
if (arr[i] == value)
{
return 0; // value found in array
}
}
return 1; // value not found in array
}
void Test(int arr[], int arrsize, int value, int expected)
{
if (unique(arr, arrsize, value) != expected)
printf("Test failed for value %d\n", value);
}
void runtests()
{
int arr[] = { 1,2,3 };
Test(arr, 4, sizeof(arr) / sizeof(*arr), 1);
Test(arr, 1, sizeof(arr) / sizeof(*arr), 0);
Test(arr, 3, sizeof(arr) / sizeof(*arr), 0);
}
#define size 5
int main()
{
int i;
int arr[size]; // declare int variable
int input; // declare int variable
printf("This program will accept unique inputted numbers that will be stored in an array\n");
for (i = 0; i < size; i++)
{
printf("Enter input %d: ", i + 1);
scanf("%d", &input);
if (unique(arr, input, i)) // value already in the array?
arr[i] = input; // no => put it there
else
{ // yes => ask again
printf(" >> %d is already in the array\n");
i--;
}
}
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
}
There are two more functions Test and runtests in this code. They are not called by this code, but they can be very useful for debugging. As an exercise try to understand why they can be useful during the debug phase of your code.
You're close, but overcomplicating it slightly.
Let's take a step back and think about this at a high level. You want to store unique inputs in the array, up to the size of the array. In pseudocode:
while array not full
prompt for and read next input
if input not already in array
store input
else
write a message
end if
end while
What's really key is that you only need one input statement - your unique function should only check for the presence of the input value in the array and return true or false. It shouldn't do any input of its own.
So your main loop is more like
while ( i < size )
{
fputs( "Gimme a number: ", stdout );
/**
* Break out of the loop if there's an error
* on input.
*/
if ( scanf( "%d", &input ) != 1 )
break;
if ( unique( arr, i, input ) )
arr[i++] = input;
else
printf( "%d already exists in the array, try again.\n", input );
}
All your unique function needs to do is cycle through the elements of the array. By calling unique with i instead of size it will only check array elements that have been written to so far and not bother with unassigned elements. This way you don't have to make sure that all of the array elements have been initialized to some known, out-of-band value that's guaranteed to compare unequal to any valid input.
You'll need to compile against C99 or later and include stdbool.h to use the bool type and the true and false constants.
#include <stdbool.h>
...
bool unique( int *arr, size_t size, int input )
{
bool result = true;
for( size_t i = 0; i < size && result; i++ )
if ( arr[i] == input )
result = false;
return result;
}
If you want to get really terse, you could directly assign the result of the Boolean expression to result:
for ( size_t i = 0; i < size && result; i++ )
result = (arr[i] == input);
but people will hit you. It's perfectly valid code, but a little eye-stabby, and most programmers aren't used to seeing Boolean expressions outside of an if, for, while, or switch statement control expression.
Finally, some suggestions:
Fix your formatting. The compiler doesn't care, but it makes it easier for other people to understand what you're trying to do and to spot mistakes.
The presence of main() in your code suggests you're using C89 or K&R C. C99 did away with implicit int declarations. You really should define main as either int main( void ) or int main( int argc, char **argv ). Furthermore, you should move to a compiler that supports later versions of C (C11 or C18).

How to break a while loop when it is false to a certain condition

I was trying to make a program where if I enter an integer, the program would find out the bigger number and subtract it by the smaller number. This part, I got it.
The problem is, the infinite loop part.
I tried to get type in two integers keep on printing with the while loop, and break when at least one character is typed in.
For example, if I type in 2 #, it would break.
But I couldn't find the write place to get the break; within the code and therefore whenever I enter a character it would keep on creating an infinite loop.
Is there any way to create a break in this code? I humbly ask for advice...
The following is the code which I couldn't put the break
(By the way, the reason I did the condition in while as sizeof(i)==4 || sizeof(j)==4 was to make it so it would only enter an integer, since the size of an integer is 4)
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i){
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
The bottom code is the one I tried to put break but failed (it kept creating an infinite loop)...
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
if (sizeof(i) == 4 || sizeof(j) == 4) {
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
else
break;
}
return 0;
}
and here's a code where I got rid of the sizeof and used while(1), though there wasn't much change in the fact that the break didn't work...
int main()
{
int i, j;
int result;
while (1){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
You can't use sizeof(i) to do run-time checks! This is a compile-time constant that, in your case (32-bit integers) will always evaluate to 4.
In order to check that two valid integers have been given, you can check the return value of the scanf function (it gives the number of fields successfully scanned):
#include <stdio.h>
int main()
{
int i, j;
int result;
while (1) {
printf("type in two integers : ");
if (scanf("%d %d", &i, &j) != 2) break; // Break here if we didn't get two integers
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
Feel free to ask fir further clarification and/or explanation.
Drop the whole concept of endless loop with break inside if.
Make a condition for the loop based on the return value of scanf(), that is practically what it is designed for.
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
printf("type in two integers : ");
while (2==scanf("%d %d", &i, &j))
{
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
printf("%d\n", result);
printf("type in two integers : ");
}
return 0;
}
I'd probably actually use do {...} while (...) with a variable storing the return value of scanf()for being used in the loop condition. I'd consider it more elegant for not having to copy the print, but I kept it closer to your code structure.
More comments on your code:
as explained in comments, sizeof() works differently than you seem to think; it is static and does not change at runtime and hence cannot be used in a loop condition
with while (sizeof(i)==4 || sizeof(j)==4){if (sizeof(i) == 4 || sizeof(j) == 4){/* a */} else {/* b */}, b cannot ever be reached, because the conditions of while and if are identical
check the possible outcomes of the if conditions inside the loop, you are leaving the one with i==j undefined and return an uninitialised value
always init all variables as a habit
for a good MRE include the include lines
On your request, here is a proposal for the do-while alternative:
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
int iScanned=0;
do
{
printf("type in two integers : ");
iScanned=scanf("%d %d", &i, &j); /* keep the return value for loop */
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
if(2==iScanned) printf("%d\n", result); /* if to avoid awkward last output */
} while (2==iScanned);
return 0;
}

Why this for loop ends in the second index?

I wrote a program that it's duty is to read 20 numbers from user and put them in a list, after that it prints the value in array from bottom to starting point.
But program stops exactly after reading second value from input.
Source code :
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i=0;i<N;i++)
{
scanf("%i", &numbers[i]);
}
for(i=N;i<0;i--)
{
printf("%i", numbers[i]);
}
return 0;
}
I use Dev-C++ 5.6.3 as my IDE and TDM-GCC 4.8.1 as my compiler. But I don't know exactly that is this an IDE related issue or not.
If you want the loop to count downwards, then this loop
for(i=N;i<0;i--)
starts at the wrong index, and fails the test condition. It should be
for(i = N - 1; i >= 0; i--)
If you want your second loop to count down, then
for(i=N;i<0;i--)
should be
for(i=N;i>0;i--)
or the loop will not execute, as i<0 is not true to start with.
and, as #WeatherVane pointed out in the comments:
scanf("%i", numbers[i]);
should be
scanf("%i", &numbers[i]);
as you need to pass a pointer to the integer you wish to fill in with the number that scanf returns.
There is some issue with the given below for loop.
for(i=N;i<0;i--)
{
printf("%i", numbers[i]);
}
return 0;
If you Want to print the array from bottom to starting point.
You can make some changes in the for loop.
Changes :
1- Change in loop while assigning the value to i :
i = N-1 -> as the size of array is 20 and array index starts with 0.
it will go 19 to 0 to print all 20 data values.
2- changes in the condition check in for loop :
i >= 0 as we printing the reverse array.
Correct for loop should be
for(i = N-1; i >= 0; i--)
{
printf("%i", numbers[i]);
}
for(i=N-1;i>=0;i--)
For n items in an array, last index will be n-1. you need to iterate from n-1 index to 0th index.
second loop must be
for(i=N;i>=0;i--)
so index will be from 19 to 0 ( 20 number )
Try This
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i = 0; i < N; i++)
{
scanf("%i", &numbers[i]);
}
for(i = N ; i >= 0; i--)
{
printf("%i ", numbers[i]);
}
return 0;
}
Try this:
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i = 0; i < N; i++)
{
scanf("%i", &numbers[i]);
}
for(i = N - 1; i >= 0; i--)
{
printf("%i ", numbers[i]);
}
return 0;
}
Remember that scanf always uses pointers.
Your second loop's condition, "i<0", is false to begin with. It should be "i > -1". You also need to make sure that the first time printf is called with index 19 and not 20. That is why I use pre decrement operator -- i.
for(i = N; i > -1; )
{
printf("%i\n", numbers[--i])
};

Count number of ones in a array of characters

I am trying to count the number of ones in an array of characters that represent a binary number with a recursive type program. However, it seems as if my program is just counting the number of characters in the array. I do not know if I am just comparing wrong or not but I can't seem to find the problem
#include <stdio.h>
# include <stdlib.h>
#include <string.h>
#define SIZE 20
int determine (char array[SIZE], int count, int track );
int main()
{
int answer = 0;
char input[SIZE]={"1001001"};
int count = 0;
int track = 0;
answer = determine(input, count, track);
printf("The number of 1's is %d ", answer);
system("PAUSE");
return 0;
}
int determine(char array[], int count, int track)
{
if (array[track] != '\0')
{
if ( array[track] == '1');
{
count++;
}
return determine(array, count, track = track+1);
}
else
{
return count;
}
}
In method determine():
if ( array[track] == '1');
remove the semicolon ;. The semicolon makes the if condition to execute an empty block. So the count++ will always execute whether the if condition succeeded(true) or not(false).
I run your code with ; and get the output:
The number of 1's is 7
And without ; :
The number of 1's is 3
if ( array[track] == '1');
should be
if ( array[track] == '1')
remove the ;
If you have the ; then irrespective of the condition evaluation result (TRUE or FALSE) count++ will get executed
Have you tried a simple countif function?
=sum if (range="1")

Code doesn't output correctly

I can't find the problem in my code, it prints only press any key to continue nothing else. I don't seem to figure out the flow of the program because of the output shown.
Help appreciated.
#include<stdio.h>
#include<stdlib.h>
int fcheck(char *name, int i, int j)
{
if (i > j)
return 1;
if (name[i] != name[j])
return 0;
else
fcheck(name, i++, j--);
return 1;
} // close fcheck
int main()
{
int c;
char name[] = "mom";
int i = 0, j = 2;
c = fcheck(name, i, j);
if (c == 1)
printf("Palindrome");
else
printf("Not a Palindrome");
return 0;
} // close main
fcheck(name,i++,j--);
only changes the values of i or j after calling fcheck. This means that you get a repeating callstack for fcheck(name,0,2) which only terminates when your stack overflows.
If you want to use recursion here, you need to use pre-increment/decrement instead
return fcheck(name,++i,--j);
Note that I've also added a return here. Without this, any string whose first and last characters match will be reported a palindrome.
1) Infinite loop problem
this line
fcheck(name,i++,j--);
should be
fcheck(name,++i,--j);
because
fcheck(name,i++,j--);
is equivalent to
fcheck(name,i,j);
i++;
j--;
so with this way of incrementation you will get an infinite loop because you are recalling fcheck() with the same arguments
and
fcheck(name,++i,--j);
is equivalent to
i++;
j--;
fcheck(name,i,j);
with this way you are not recalling fcheck() with the same arguments. So it should fix your infinite loop problem
2) should add return after the recursive call
As mentioned in the other answer, you should add return when you call the recursive function
return fcheck(name, ++i, --j);
int fcheck(char *name, int i, int j){
if (i > j)
return 1;
if (name[i] != name[j])
return 0;
return fcheck(name, i+1, j-1);
}

Resources