recursive find number in between in C - c

I want to find the number within a range in an array and must be in a recursive way. The function variables couldn't be modified.
Let's say in the range of 2 and 3
The input is : int a[] = {4, 1, 3, 1, 3, 2};
and the output will be = {3,3,2} , 3 found
Not sure how to code the recursive function in this case. The below I have tried not working.
int within(int a[], int N, int lower, int upper, int result[])
{
if(N == 1 && N <= upper && N>= lower)
return a[0];
return within(&a[1], N-1, lower, upper, result);
}
int main()
{
int a[] = {4, 1, 3, 1, 3, 2};
int result[6] = {0};
int i, nResult;
nResult = within(a, 6, 2, 3, result);
printf("%d data passed the bounds\n", nResult);
for (i = 0; i < nResult; i++){
printf("%d ", result[i]);
}
printf("\n");
return 0;
}

I want to find the number within a range in an array
Let's say in the range of 2 and 3
Normally a for loop or similar would be so much easier here
If it has to be recursive....
// need to have another number - r - number in range
// r starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int r, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[r]= a[0];
r++;
}
if(N==0) {
return r;
} else {
r = within(&a[1], N-1, lower, upper, r, result);
return r;
}
}
the function will give a return value of the number of values found within the range.
The code above is recursive, but so much more complicated and fragile than a simple loop... such as the fragment below
for (i=0;i<N;i++) {
if(a[i] <= upper && a[i]>= lower) {
result[r]= a[i];
r++;
}
}
If it has to be recursive wihtout r...
// need to have another number - result[0] - number in range
// result[0] starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[0]++;
result[result[0]]= a[0];
}
if(N==0) {
return result[0];
} else {
result[0] = within(&a[1], N-1, lower, upper, result);
return result[0];
}
}
now result conatins
{number in range, first number in range, second number in range....}

Something like this. If you want to implement a recursive function, try to do it in the way that the recursive call happens at the end.
#include <stdio.h>
int find_in_range(int* out, int const *in, int length, int from, int to)
{
if (length == 0)
{
return 0;
}
int addon;
if (*in >= from && *in <= to)
{
*out = *in;
++out;
addon = 1;
}
else
{
addon = 0;
}
return find_in_range(out, in + 1, length - 1, from, to) + addon;
}
#define N 6
int main()
{
int in[N] = {4, 1, 3, 1, 3, 2};
int out[N] = {0};
int num_found = find_in_range(out, in, N, 2, 3);
for (int i = 0; i < num_found; ++i)
{
printf("%d ", out[i]);
}
printf("\n");
return 0;
}

You can modify the following code as per your requirements. This is just a proof of concept code:
#include <stdio.h>
#include <stdlib.h>
static int result[4];
static int ctr1 = 0;
static int ctr2 = 0;
void recFind(int* arr, int* key){
if(ctr2 == 8)
return;
if(*arr >= key[0] && *arr <= key[1])
result[ctr1++] = *arr;
arr++;
ctr2++;
recFind(arr, key);
}
int main(){
int arr[] = {1,3,3,6,4,6,7,8};
int key[] = {1,4};
recFind(arr, key);
printf(" { ");
for(int i = 0; i < 4; i++){
printf("%d ", result[i]);
}
printf("}\n");
}

As it follows from the description of the assignment the function should provide two values: the number of elements that satisfy the condition and an array that contains the elements themselves.
It is evident that the array should be allocated dynamically. And it is logically consistent when the function itself returns the number of elements while the pointer to the generated array is passed by reference as an argument.
The recursive function can look the following way
#include <stdio.h>
#include <stdlib.h>
size_t get_range( const int a[], size_t n, int lower, int upper, int **out )
{
size_t m;
if ( n )
{
m = get_range( a, n - 1, lower, upper, out );
if ( lower <= a[n-1] && a[n-1] <= upper )
{
int *tmp = realloc( *out, ( m + 1 ) * sizeof( int ) );
if ( tmp )
{
tmp[m] = a[n-1];
*out = tmp;
++m;
}
}
}
else
{
*out = NULL;
m = 0;
}
return m;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
int lower = 2, high = 3;
int *out;
size_t n = get_range( a, N, lower, high, &out );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", out[i] );
}
putchar( '\n' );
free( out );
return 0;
}
The program output is
2 3 3 2

Below codes will work for you in recursive way. If you don't want to print the numbers just comment out printf statement inside function printfRange. Hope you can understand the logic :-
int within(int *a, int rngH, int rngL, int length)
{
int len = length;
static int i = 0;
static int found = 0;
if(len <=0 )
{
return i;
}
if (*a == rngH)
{
printf("%d,",*a);
i++;
found = 1;
within(++a,rngH, rngL,--len);
}
else if(*a == rngL && found > 0)
{
printf("%d,",*a);
i++;
within(++a,rngH, rngL,--len);
}
else
{
within(++a,rngH, rngL,--len);
}
return i;
}
int main() {
int a[] = {4, 1, 3, 1, 3, 2};
int total = within(a,3,2,6);
printf("\n");
printf("Total :%d\n",total);
return 0;
}

Related

Print prime numbers using pointer arithmetic

My function writePrime has to write all prime numbers from array using pointer arithmetic. I cannot use any other function except main and writePrime.
#include <stdio.h>
void writePrime(int arr[], int n) {
int *q = arr, *qq = arr, i, prime;
while (q < arr + n) {
while (qq < arr + n) {
i = 1;
if (*qq % i != 0)
continue;
else
prime = 1;
i++;
qq++;
}
if (prime == 1)
printf("%d ", *q);
q++;
}
}
int main() {
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 92, 93, 94, 95, 96};
int n = sizeof(arr) / sizeof(*arr);
writePrime(arr, n);
return 0;
}
This code just prints the same unchanged array. How could I modify this to work?
The variable n should be declared as having the type size_t
size_t n = sizeof(arr) / sizeof(*arr);
because it is the type of an expression with the sizeof operator.
So the function should be declared like
void writePrime( const int arr[], size_t n );
Using two loops with two pointers within the function does not make a sense.
Each variable is divisible by 1. So this code snippet
i = 1;
if (*qq % i != 0)
continue;
else
prime = 1;
also does not make any sense.
And you are using initially uninitialized variable prime that must be reset before processing each element of the array.
The function can be defined the following way
void writePrime( const int arr[], size_t n )
{
for ( const int *p = arr; p != arr + n; ++p )
{
int prime = *p % 2 == 0 ? *p == 2 : *p != 1;
for ( int i = 3; prime && i <= *p / i; i += 2 )
{
if ( *p % i == 0 ) prime = 0;
}
if ( prime ) printf( "%d ", *p );
}
putchar( '\n' );
}

Why am I seeing this bizarre behaviour?

The code is recursive dynamic programming for the 0/1 Knapsack problem.
So let me start by saying that the code seems correct because when I run it, It shows results but only if I uncomment the printf line (please see the highlighted part) and it has nothing to do with the solution (I used it only for testing purpose) which I find totally weird. Can somebody please tell me why is this happening.
int main() {
int DP_Recursive(int W, static int wt[], static int val[], int n, static int dp[][]);
static int wt[5] = { 5, 10, 20, 30 };
static int val[5] = { 50, 60, 100, 120 };
static int dp[5][60]; //marker 2-D array
for (int i = 0; i <= 5; i++) {
for (int w = 0; w <= 50; w++) {
dp[i][w] = -1;
}
}
printf("The total loot is %d$.", DP_Recursive(50, wt, val, 2, dp));
}
//Recursive D.P. solution
int DP_Recursive(int W, static int wt[], static int val[], int n, static int dp[5][60]) {
//-------**HIGHLIGHTED PART**-----------
printf("%d", dp[2][30]);
//--------------------------
//Base case
if (n == 0 || W == 0)
return 0;
if (dp[n][W] != -1)
return dp[n][W];
if (wt[n-1] > W) {
dp[n][W] = DP_Recursive(W, wt, val, n - 1, dp);
return dp[n][W];
} else {
dp[n][W] = max(val[n-1] + DP_Recursive(W - wt[n-1], wt, val, n-1, dp),
DP_Recursive(W, wt, val, n-1, dp));
}
return dp[n][W];
}
There are multiple issues int the code:
[Major] The prototype for DP_recursive is incorrect: use int DP_Recursive(int W, int wt[], int val[], int n, static int dp[5][60]) in both the function declaration before the main() function (outside the body of main) and for the function definition itself.
[Minor] the arrays in main() do not need to be declared static.
[Major] the initialization loops run one step too far: for (int i = 0; i <= 5; i++) iterates 6 times with i ranging from 0 to 5 inclusive. You should use < instead of <= in both loops. As a rule of thumb, always check twice before using <=, and always prefer excluded upper bounds.
[Major] the inner initialization loop uses 50 instead of 60 as the upper bound, causing the array to be partially initialized and result incorrect (undefined behavior) instead of 110. It is better to use a countof macro to get the number of elements in an array.
[Minor] you should end the output with a newline (\n)
[Minor] main() should return 0 upon successful termination.
you did not post the definition of max, it is advisable to define it as a function.
the include file <stdio.h> is missing too.
Here is a modified version:
#include <stdio.h>
int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]);
int max(int a, int b) {
return a < b ? b : a;
}
#define countof(a) (sizeof(a) / sizeof((a)[0])) // number of elements in an array
int main() {
int wt[5] = { 5, 10, 20, 30 };
int val[5] = { 50, 60, 100, 120 };
int dp[5][60]; //marker 2-D array
for (size_t i = 0; i < countof(dp); i++) {
for (size_t w = 0; w < countof(dp[i]); w++) {
dp[i][w] = -1;
}
}
printf("The total loot is %d$.\n", DP_Recursive(50, wt, val, 2, dp));
return 0;
}
//Recursive D.P. solution
int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]) {
//-------**HIGHLIGHTED PART**-----------
printf("%d ", dp[2][30]);
//--------------------------
//Base case
if (n == 0 || W == 0)
return 0;
if (dp[n][W] != -1)
return dp[n][W];
if (wt[n-1] > W) {
dp[n][W] = DP_Recursive(W, wt, val, n - 1, dp);
return dp[n][W];
} else {
dp[n][W] = max(val[n-1] + DP_Recursive(W - wt[n-1], wt, val, n-1, dp),
DP_Recursive(W, wt, val, n-1, dp));
}
return dp[n][W];
}

Binary search implementation in C

First time posting here. I recently implemented Binary Search but sometimes my outputs will return a giant negative number instead. Now my first thought is that I'm printing a number where my pointer is pointing at a random memory location. Can someone help me with the logic and how I can improve my code?
#include <stdio.h>
#include <stdlib.h>
int binarysearch(int *array, int size, int target);
int main() {
int array[] = { 1, 2, 3, 4, 5, 6 };
printf("%d\n", binarysearch(array, 8, 15));
return 0;
}
int binarysearch(int *array, int size, int target) {
int mid;
mid = size / 2;
if (size < 1) {
return -1;
}
if (size == 1) {
return array[0];
}
if (target == array[mid]) {
return target;
} else
if (target < array[mid]) {
binarysearch(array, mid, target);
} else{
binarysearch(array + mid, size - mid, target);
}
}
For starters you call the function with an invalid number of elements in the array that has only 6 elements.
int array[] = { 1, 2, 3, 4, 5, 6 };
printf("%d\n", binarysearch(array, 8, 15));
^^^
Also this snippet
if (size == 1) {
return array[0];
}
is incorrect. It is not necessary that the first element is equal to target.
This statement
binarysearch(array + mid, size - mid, target);
has to be written like
binarysearch(array + mid + 1, size - mid - 1, target);
And at last the function has undefined behavior because it returns nothing in these cases
if (target < array[mid]) {
binarysearch(array, mid, target);
} else{
binarysearch(array + mid, size - mid, target);
}
You need to write
if (target < array[mid]) {
return binarysearch(array, mid, target);
} else{
return binarysearch(array + mid, size - mid, target);
}
And two words about the programming style. It is better to name the function either like binary_search or like binarySearch or at last like BinarySearchthan like binarysearch.
In general it is not a good design of the function. Imagine that the array has an element with the value -1. How will you determine whether this element is present in the array or is absent?
Usually such functions return pointer to the target element in case if it is found or NULL pointer otherwise.
Here is a demonstrative program that shows how this approach can be implemented.
#include <stdio.h>
int * binary_search( const int *a, size_t n, int target )
{
if ( n == 0 ) return NULL;
size_t middle = n / 2;
if ( a[middle] < target )
{
return binary_search( a + middle + 1, n - middle - 1, target );
}
else if ( target < a[middle] )
{
return binary_search( a, middle, target );
}
return a + middle;
}
int main(void)
{
int array[] = { 1, 2, 3, 4, 5, 6 };
const size_t N = sizeof( array ) / sizeof( *array );
for ( int i = 0; i < 8; i++ )
{
int *target = binary_search( array, N, i );
if ( target )
{
printf( "%d is found at position %d\n", *target, ( int )(target - array ) );
}
else
{
printf( "%d is not found\n", i );
}
}
return 0;
}
The program output is
0 is not found
1 is found at position 0
2 is found at position 1
3 is found at position 2
4 is found at position 3
5 is found at position 4
6 is found at position 5
7 is not found
By the way according to the C Standard function main without parameters shall be declared like
int main( void )
You call binarysearch(array, 8, 15)) but your array has only 6 entries.
Here is how to compute the proper size automatically:
int main(void) {
int array[] = { 1, 2, 3, 4, 5, 6 };
printf("%d\n", binarysearch(array, sizeof(array) / sizeof(array[0]), 15));
return 0;
}
Note that your function binarysearch has problems too:
Returning the array entry is bogus, what do you return if the target is less than the first entry? -1 is not necessarily less than the first entry.
You are supposed to return the index into the array with the entry if found and -1 if not found.
When you recurse, you do not return the value from these recursive calls: you should compile with warnings enabled (for example: gcc -Wall -W) and look at all the helpful diagnostic messages the compiler produces.
Here is a modified version:
int binarysearch(const int *array, int size, int target) {
int a, b;
for (a = 0, b = size; a < b;) {
int mid = a + (b - a) / 2;
if (target <= array[mid]) {
b = mid;
} else {
a = mid + 1;
}
}
// a is the offset where target is or should be inserted
if (a < size && target == array[a])
return a;
else
return -1;
}
Notes:
Computing mid = (a + b) / 2; would be potentially incorrect for large sizes as there may be an arithmetic overflow. mid = a + (b - a) / 2; does not have this problem since a < b.
The time-complexity is O(Log N), and for a given size, the function performs the same number of steps for all target values.
If the array contains multiple identical values equal to target, the index returned by binarysearch is that of the matching entry with the lowest index.
You could make this problem easier by using the bsearch function offered by the <stdlib.h> library.
Something like this:
#include <stdio.h>
#include <stdlib.h>
int cmpfunc(const void * a, const void * b);
int
main(void) {
int array[] = {1, 2, 3, 4, 5, 6};
size_t n = sizeof(array)/sizeof(*array);
int *item;
int key = 15;
item = bsearch(&key, array, n, sizeof(*array), cmpfunc);
if (item != NULL) {
printf("Found item = %d\n", *item);
} else {
printf("Item = %d could not be found\n", key);
}
return 0;
}
int
cmpfunc(const void * a, const void * b) {
return (*(int*)a > *(int*)b) - (*(int*)a < *(int*)b);
}
If you don't want to use bsearch, then this method will be fine also:
#include <stdio.h>
#include <stdlib.h>
#define BSFOUND 1
#define BS_NOT_FOUND 0
int cmpfunc(const void * a, const void * b);
int binary_search(int A[], int lo, int hi, int *key, int *locn);
int
main(void) {
int array[] = {1, 2, 3, 4, 5, 6};
size_t n = sizeof(array)/sizeof(*array);
int key = 4, locn;
if ((binary_search(array, 0, n, &key, &locn)) == BSFOUND) {
printf("Found item = %d\n", array[locn]);
} else {
printf("Item = %d cound not be found\n", key);
}
return 0;
}
int
binary_search(int A[], int lo, int hi, int *key, int *locn) {
int mid, outcome;
if (lo >= hi) {
return BS_NOT_FOUND;
}
mid = lo + (hi - lo) / 2;
if ((outcome = cmpfunc(key, A+mid)) < 0) {
return binary_search(A, lo, mid, key, locn);
} else if(outcome > 0) {
return binary_search(A, mid+1, hi, key, locn);
} else {
*locn = mid;
return BSFOUND;
}
}
int
cmpfunc(const void * a, const void * b) {
return (*(int*)a > *(int*)b) - (*(int*)a < *(int*)b);
}

palindrome checker algorithm

i'm having problems writing this excercise.
this should evaluate if a given array contains a palindrome sequence of numbers, the program builds correctly but doesn't run (console remains black). where am i wrong on this? thanks for all help!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
//i'm using const int as exercise demand for it
//should i declare size as int when giving it to function? also if it's been declared?
//i'm a bit confused about that
int palindrome(const int a[], int p, int size);
int main()
{
int a[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0};
int p = 1; //i'm not using boolean values, but i think should work anyway, right?
p = palindrome(a, p, SIZE);
if (p)
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");
return 0;
}
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
while (p) {
for (j = 0; j < (SIZE / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]) //i think i might be wrong on this, but don't know where i'm in fault
p = 0;
}
}
return p;
}
p.s.
how can i activate debugger "watches" on Code Blocks to look at others function variables? (i put a stop on main function)
You don't need while (p) { loop. It is possible to have infinite loop here (and you have it!), because if you don't change p, this loop never stops.
You mix size and SIZE in the implementation of palindrome() (mid is half of size, but the whole loop is from 0 to SIZE-1).
Also it is better to move int p = 1; in the beginning of implementation of palindrome() (and to remove int p from list of it's parameters).
Just try this:
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
for (j = 0; j < (size / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]);
p = 0;
break;
}
}
return p;
}
here's an alternative without p where palindrome returns 0 or 1
int palindrome(const int a[], int size)
{
int j , k , ret;
for (j = 0 , k = size - 1 ; j < k; j++ , k--)
{
if (a[j)] != a[k])
{
ret = 0;
break;
}
}
if(j >= k)
ret = 1;
return ret;
}
you can call palindrome in the if statement in main like this :
if(palindrome(a , SIZE))
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");

Longest Common Contiguous Substring Length in C

So the following is the code I wrote up for the algorithm. I cannot find what is wrong with it. The test cases are supposed to yield 12, 4, and 3 respectively but instead yield 8, 1, and 2 respectively. Did I misunderstand the algorithm structure?
#include <stdio.h>
#define MAX_STRING_LENGTH 100
void clear_memo(int memo[][MAX_STRING_LENGTH]);
// Returns the larger of a and b
int max(int a, int b){
return a ? a > b : b;
}
int lcs_length(char A[], char B[], int i, int j, int memo[][MAX_STRING_LENGTH]){
if(i == 0 && j == 0){
clear_memo(memo);
}
if (memo[i][j] > 0){
return memo[i][j];
}
if (A[i] == '\0' || B[j] == '\0'){
memo[i][j] = 0;
}
else if(A[i] == B[j]){
memo[i][j] = 1 + lcs_length(A, B, i+1, j+1, memo);
}
else{
memo[i][j] = max(lcs_length(A, B, i+1, j, memo), lcs_length(A, B, i, j+1, memo));
}
return memo[i][j];
}
// Makes all the entries zero in the memo array
void clear_memo(int memo[][MAX_STRING_LENGTH]){
for(int i = 0; i < MAX_STRING_LENGTH; i++){
for(int j = 0; j < MAX_STRING_LENGTH; j++){
memo[i][j] = 0;
}
}
}
// Tests the lcs_length() function
int main(){
int memo[MAX_STRING_LENGTH][MAX_STRING_LENGTH];
char a[] = "yo dawg how you doing?";
char b[] = "yo dawg zhzzzozw?";
printf("%d\n", lcs_length(a,b,0,0,memo));
char c[] = "nano";
char d[] = "nematode knowledge";
printf("%d\n", lcs_length(c,d,0,0,memo));
char e[] = "abcd";
char f[] = "abdc";
printf("%d\n", lcs_length(e,f,0,0,memo));
return 0;
}
Your max is wrong. a? a>b:b;
means if a is non zero, return a>b( which returns 1 if a>b and 0 otherwise) and if a is zero, returns b. So a is never returned even if it is greater and b is returned only if a is 0 irrespective of which is greater.
Use
int max(int a, int b){
return a>b?a:b;
}

Resources