recursive function to locate last occurence of an element - c

I am trying to write a recursive function in C,
Given an array, size of the array as well as the element int target, I want to find the index of int target's last occurence.
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main()
{
int numArray[80];
int target, i, size;
printf("Enter array size: \n");
scanf("%d", &size);
printf("Enter %d numbers: \n", size);
for (i=0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: \n");
scanf("%d", &target);
printf("rLookupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target)
{
}
However, I have been stuck for hours.
I am a beginner to recursive functions and any help will be greatly appreciated!
Some examples:
Enter array size:
5
Enter 5 numbers:
2 1 3 2 4
Enter the target number:
2
rLookupAr(): 3

If you're after the last occurrence, then you can start your search at the end of the array and work backwards.
C arrays are referenced by a pointer to any element and a length or index upper-bound value, which you have.
One way of looking at recursive functions is asking "is each step of the algorithm just repeating the whole thing, just on a decreasing subset of the input data?" - consider problems like processing trees (where each child node is a tree itself) or operations like quicksort (where each pivot gives you two more sub-sections which you pivot again, and so on).
Consider that finding a value in an array of [0...N] is the same as finding the value by checking [0] and then checking [1...N], then repeating yourself all over again by checking [1] and then checking [2..N]...hopefully you're seeing a pattern emerging.
For working backwards, given the array's start and length N, you'd check [N] first, then repeat with the range [0..(N-1)], then check [N-1] then repeat with [0...(N-2)].
I hope that will enable you to come to a solution without me just giving you the answer.

You can define rLookupAr() function as following. See the complete working code here:
int rLookupAr(int array[], int size, int target)
{
if(size < 1) return -1;
size--;
if(array[size] == target) return size;
return rLookupAr(array, size,target);
}
Note: rLookupAr() function will return -1 if target value is not found in array array.
OUTPUT:
Enter array size: 5
Enter 5 numbers: 2 1 3 2 4
Enter the target number: 2
rLookupAr(): 3
Following is the complete code:
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main()
{
int numArray[80];
int target, i, size;
printf("Enter array size: \n");
scanf("%d", &size);
printf("Enter %d numbers: \n", size);
for (i=0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: \n");
scanf("%d", &target);
printf("rLookupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target)
{
if(size < 1) return -1;
size--;
if(array[size] == target) return size;
return rLookupAr(array, size,target);
}

Please find the recursive function below:
int rLookupAr (int array[], int size, int target)
{
if(size<=0) return -1;
if(array[size-1] == target)
return size-1;
else
return rLookupAr (array, size-1, target); //recurse
}
basically the functions starts from the end because the last occurance is being sought. Depending on whether the target is found or not it further recurses down the array.
Complete code:
#include <stdio.h>
int rLookupAr (int array[], int size, int target);
int
main ()
{
int numArray[80];
int target, i, size;
printf ("Enter array size: \n");
scanf ("%d", &size);
printf ("Enter %d numbers: \n", size);
for (i = 0; i < size; i++)
scanf ("%d", &numArray[i]);
printf ("Enter the target number: \n");
scanf ("%d", &target);
printf ("rLookupAr(): %d", rLookupAr (numArray, size, target));
return 0;
}
int
rLookupAr (int array[], int size, int target)
{
if(size<=0) return -1;
if(array[size-1] == target)
return size-1;
else
return rLookupAr (array, size-1, target); //recurse
}
Output:
Enter array size:
5
Enter 5 numbers:
2
1
3
2
4
Enter the target number:
2
rLookupAr(): 3

Here is a solution with a single statement:
int rLookupAr(int array[], int size, int target) {
return size-- <= 0 ? -1 : array[size] == target ? size : rLookup(array, size, target);
}
Using a recursive solution for a simple case like this is only meant as an exercise. C compilers are not required to perform tail recursion optimization to convert this code to a loop, so this recursive implementation can easily cause a stack overflow for a moderately large array.

I am a beginner to recursive functions
Recursive functions get a bad name with linear reduction.
Instead break the problem in 2 to achieve a a recursive depth of log2(n).
int rLookupAr(int array[], int size, int target) {
if (size < 1) {
return -1;
}
int mid = size/2;
int right = rLookupAr(array + mid, size - mid, target);
if (right != -1) {
return right + mid;
}
int left = rLookupAr(array, mid, target);
return left;
}

int rLookupAr(int input[], int size, int x) {
/* Don't write main().
Don't read input, it is passed as function argument.
Return output and don't print it.
Taking input and printing output is handled automatically.
*/
if(size==0)
{
return -1;
}
//return -1;
int ans=lastIndex(input+1,size-1,x);
if(ans!=-1)
{
return ans+1;
}
else{
if(input[0]==x)
{
return ans+1;
}
else
{
return -1;
}
}
}

int lastIndex(int input[], int size, int x)
{
if (size == 0)
{
return -1;
}
int answer = lastIndex(input + 1, size - 1, x);
if (answer != -1)
{
return answer + 1;
}
if (input[0] == x)
{
return 0;
}
else
{
return -1;
}
}
int main()
{
int input[] = {9, 8, 10, 8};
int x = 8;
int size = 4;
cout << lastIndex(input, size, x);
return 0;
}

Related

Adding the same number multiple times to an empty array in C

This is a piece of code to add the same number multiple times to an empty array but when I am printing the now non empty array, I am getting some other values:
#include<stdio.h>
#include<stdlib.h>
void sort_0(int arr[100], int i, int n){
int final_array[100], c=0;
// Count the number of '0' in the array
for(i=0;i<n;i++){
if(arr[i] == 0){
c++;
}
}
// Add the c number of '0' to the final_array
for(i=0;i<c;i++){
scanf("%d",final_array[i]);
}
for(i=0;i<c;i++){
printf("%d ", final_array[i]);
}
}
int main(){
int arr[100], i, n;
// Entering the size of the array
scanf("%d", &n);
// Entering n elements into the array
for(i=0;i<n;i++){
scanf("%d", &arr[i]);
}
sort_0(arr,i,n);
return 0;
}
In the above code, the number of times 0 appears in the array is counted. Then the count is taken as the range and 0 is adding to the empty array final_array count times.
If c = 5, the final_array = {0,0,0,0,0}
Expected Output:
arr = {0,1,4,3,0}
Output = 2
I am not getting any output
Since you don't know how much 0 you'll need to add to your array_final I figured out that a better solution could be to create that array after you have the number of 0 of the first array. Also, I see no reason why you were passsing i to the function since you can simply define it in the function itself.
void sort_0(int arr[10], int n, int* c){
int i;
for(i=0;i<n;i++){
if(arr[i] == 0){
(*c)+= 1;
}
}
}
int main (void) {
int size;
printf("Enter array size: ");
scanf("%d", &size);
int arr[size];
for (int i=0;i<size;i++) {
scanf("%d",&arr[i]);
}
int c = 0;
sort_0(arr, size, &c);
printf("C is: %d\n",c);
int* final_array;
if ((final_array=malloc(c * sizeof(int)))==NULL) // should always check malloc errors
{
perror("malloc");
return -1;
}
for (int i=0;i<c;i++) {
final_array[i]= 0;
}
printf("{");
for (int i=0;i<c-1;i++) {
printf("%d,", final_array[i]);
}
printf("%d}\n",final_array[c-1]);
return 0;
}

C recursive program to print all prime factors of a given number from the biggest factor to the smallest

i'm trying to write a program that print the prime factors of a given number ,but i need to print them from the biggest factor to the smallest, for example:
for the input 180 the output will be: 5*3*3*2*2,
any suggestions? here is what i got for now :
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
printf("*%d",num);
print_fact (n/num);
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
for this code the output is :
*2*2*3*3*5
You can simply print the output after the recursive call returns. You need to slightly modify how you display the *, which I leave to you.
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
// printf("*%d",num); // remove from here
print_fact (n/num);
printf("%d ",num); // put here
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
The output this gives on input 180 is:
5 3 3 2 2
Aside, there are much more efficient ways of actually finding the numbers though.
It is much faster to find them in the ascending order, mathematically speaking. Much, much faster.
The solution, if you don't want to bother yourself with dynamic arrays, is recursion. Find the lowest prime factor, recurse on the divided out number (num /= fac), and then print the earlier found factor, which will thus appear last.
to change the order in which they are printed, you could put the printf statement after the print_fact statement. To get rid of thew leading *, you would probably want to store the results and display them after computation
well, i'm trying to optimize my algorithm
this is my code for now:
functions code
#include "prime_func.h"
int divisors(int x) /* Function To set the maximum size of the future array,
Since there is no way to find the number of primary factors
without decomposing it into factors,
we will take the number of total number divisors
(which can not be greater than the number of primary factors) */
{
int limit = x;
int numberOfDivisors = 0;
if (x == 1) return 1;
for (int i = 1; i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
if (limit != i) {
numberOfDivisors++;
}
numberOfDivisors++;
}
}
return numberOfDivisors;
}
void find_fact(int n, int *arr, int size, int i) //func to find the factors and apply them in allocated array
{
int num = 2;
if (n < 2)
{
printf("error\n");
return;
}
while (n%num != 0)
num++;
arr[i++] = num;
find_fact(n / num, arr, size, i);
}
void print_fact(int *arr, int size) // func to print the array in reverse
{
int i = 0;
int first;
first = FirstNumToPrint(arr, size);
for (i = first; i>0; i--)
printf("%d*", arr[i]);
printf("%d", arr[0]);
}
int FirstNumToPrint(int *arr, int size) // func to find the first number to print (largest prime factor)
{
int i;
for (i = 0; i < size; i++)
if (arr[i] == 0)
return i - 1;
}
int first_prime(int num) // for now i'm not using this func
{
for (int i = 2; i<sqrt(num); i++)
{
if (num%i == 0)
{
if (isprime(i));
return(i);
}
}
}
bool isprime(int prime) // for now i'm not using this func
{
for (int i = 2; i<sqrt(prime); i++)
{
if (prime%i == 0)
return(false);
}
return(true);
}
main code
#include "prime_func.h"
int main()
{
int n,i=0; // first var for input, seconde for index
int *arr; // array for saving the factors
int size;//size of the array
printf("please insert a number \n");// asking the user for input
scanf("%d", &n);
size = divisors(n); //set the max size
arr = (int *)calloc(size,sizeof(int)); //allocate the array
if (arr == NULL) // if the allocation failed
{
printf("error\n");
return 0;
}
find_fact(n, arr,size,i);// call the func
print_fact(arr,size); //print the result
free(arr); // free memo
}
#WillNess #GoodDeeds #mcslane

output different elements from two arrays

I am trying to output different elements from two arrays. So if i have an array A: {9, 0, 1} and B is {0, 8, 1}, I need to output an element which included in the first set, but are not included in the second :9 Can not think how I should compare all elements from the first array with the second one.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10],b[10],c,n,i,j;
printf("enter a number: ");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter a[%d]: ",i+1);
scanf("%d",&a[i]);
}
printf("\n");
for(j=0;j<n;j++){
printf("Enter b[%d]: ",j+1);
scanf("%d",&b[j]);
}
for (i = 0; i < n; i++) {
printf("%d ", a[i]); }
printf("\n");
for (i = 0; i < n; i++) {
printf("%d ", b[i]); }
printf("\n");
return 0;
}
I'd like to show my thoughts but i think it's stupid:
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(a[i]!= b[j]){
c=a[i];
}
}
printf("%d ",c);
}
This can be easily solved using Binary search. Follow the simple steps.
Step 1: Sort the second array.
Step 2: For each element of the first array, binary search it in the second array, if its not present , print it, otherwise dont.
The time complexity is O(m log n), where m is length of first array and n is length of second array.
If you want a more efficient solution, as suggested by #Sumeet Singh, you can sort the second array with qsort, then find similar elements from the first array with bsearch(binary search).
Your current solution is O(N^2) time, which will be very slow with large n, but you can achieve more efficiency with this approach.
Here is some code I wrote up with demonstrates this:
#include <stdio.h>
#include <stdlib.h>
#define NNUMBERS 10
void get_array_input(int array1[], int array2[], size_t *n);
void search_elements(int array1[], int array2[], size_t n);
void print_arrays(int array[], size_t n);
int cmp_func(const void *a, const void *b);
int main(void) {
int array1[NNUMBERS], array2[NNUMBERS];
size_t n;
/* input from user */
get_array_input(array1, array2, &n);
printf("\nFirst array: ");
print_arrays(array1, n);
printf("\nSecond array: ");
print_arrays(array2, n);
/* sorting the second array */
qsort(array2, n, sizeof(*array2), cmp_func);
printf("\nSorted Second array: ");
print_arrays(array2, n);
/* the search begins */
search_elements(array1, array2, n);
return 0;
}
void get_array_input(int array1[], int array2[], size_t *n) {
size_t i;
printf("Enter n: ");
if (scanf("%zu", n) != 1) {
printf("Invalid n value.\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < *n; i++) {
printf("Enter array1[%zu]: ", i);
if (scanf("%d", &array1[i]) != 1) {
printf("Invalud array value.\n");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < *n; i++) {
printf("Enter array2[%zu]: ", i);
if (scanf("%d", &array2[i]) != 1) {
printf("Invalud array value.\n");
exit(EXIT_FAILURE);
}
}
}
void search_elements(int array1[], int array2[], size_t n) {
size_t i;
void *key;
printf("\nElements in first array which are not in second array: ");
for (i = 0; i < n; i++) {
key = bsearch(&array1[i], array2, n, sizeof(*array2), cmp_func);
if (!key) {
printf("%d ", array1[i]); /* not found, so print it */
}
}
printf("\n");
}
void print_arrays(int array[], size_t n) {
size_t i;
for (i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
/* cmp function needed for qsort and bsearch */
/* many ways to write these */
int cmp_func(const void *a, const void *b) {
const int *num1 = (const int *)a;
const int *num2 = (const int *)b;
if (*num1 > *num2) {
return +1;
} else if (*num1 < *num2) {
return -1;
}
return 0;
}
Input:
Enter n: 3
Enter array1[0]: 9
Enter array1[1]: 0
Enter array1[2]: 1
Enter array2[0]: 0
Enter array2[1]: 8
Enter array2[2]: 1
Output:
First array: 9 0 1
Second array: 0 8 1
Sorted Second array: 0 1 8
Elements in first array which are not in second array: 9
You are on the right path. You are taking each value from the first array and comparing to each value in the second.
What you need to do now is to only print a[i] if there isn't any b[j] such that they are the same. The easiest way is to set a flag (say, unique=1). You can give this flag any name you find suitable, but in this case I'm thinking it says that the number a[i] is "unique" to the array a. So in this case you start with the premise that, yes, you won't find a[i] in the arrayb, and then you try to disprove your assumption. If at any time of you search you find an instance of a[i] == b[j], then your premise was wrong, so you set unique=0.
After you have compared this a[i] against all elements in b, you review your flag. And you print the appropriate message depending on whether you found this element in b or not.
Note that this assumes that the same value doesn't appear twice in a.
I have edited your code a little bit and this code gives you desired output:
#include <stdio.h>
int main(void){
int a[10],b[10],c,n,i,j;
int counter=0;
printf("enter a number: ");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter a[%d]: \n",i+1);
scanf("%d",&a[i]);
}
printf("\n");
for(j=0;j<n;j++){
printf("Enter b[%d]: \n",j+1);
scanf("%d",&b[j]);
}
for(i=0;i<n;i++){
counter=0;
for(j=0;j<n;j++){
if(a[i]!=b[j]){
counter++;
}
}
if(counter == n){
printf("%d ",a[i]);
}
}
return 0;
}
Let's explain this code a little bit:
In the last nested for loop, outer loop takes one element from array a. Inner loop gets every element of array b in order to compare it to taken element from array a. If none of the elements of array b is equal to a's taken element, counter will be equal to n(array size). Then we can print this element taken from a(it means there is no match between this taken element and array b's all of elements.

Array same element in C

c finding the array of the same element
A function called rLookupAr() takes in three parameters, array, size and target, and returns the subscript of the last appearance of a number in the array. The parameter size indicates the size of the array. For example, if array is {2,1,3,2,4} and target is 3, it will return 2. With the same array, if target is 2, it will return 3. If the required number is not in the array, the function will return –1. The function prototype is given below.
int rLookupAr(int array[], int size, int target);
Write a C program to test the function.
A sample input and output session is given below:
Enter array size: 5 Enter 5 numbers: 2 1 3 2 4 Enter the target number: 2 rLookupAr() = 3
Enter array size: 5 Enter 5 numbers: 2 1 3 2 4 Enter the target number: 5 rLookupAr() = -1
This is my code
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main() {
int numArray[80];
int target, i, size;
printf("Enter array size: ");
scanf("%d", &size);
printf("Enter %d numbers: ", size);
for (i = 0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: ");
scanf("%d", &target);
printf("rLoopupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target) {
int j,i;
for (j = 0; j < size; j++)
if(array[i] == target)
return j;
return -1;
}
I do not know how to implement when same array elements numbers are the same as bolded
You can code it looping through the array in reverse way like
int rLookupAr(int array[], int size, int target) {
int j;
for (j = size-1; j >= 0; j--)
if (array[j] == target)
return j;
return -1;
}
Or looping through the whole and store the value in a lookup variable
int rLookupAr(int array[], int size, int target) {
int j;
char found = -1;
for (j = 0; j < size; j++)
if (array[j] == target)
found = j;
return found;
}

Reverse array with recursion in C programming

I was having some problem when trying to do a reverse array using recursion. Here is the function prototype:
void rReverseAr(int ar[ ], int size);
And here is my code:
int main()
{
int ar[10], size, i;
printf("Enter array size: ");
scanf("%d", &size);
printf("Enter %d numbers: ", size);
for (i = 0; i<size; i++)
scanf("%d", &ar[i]);
rReverseAr(ar, size);
printf("rReverseAr(): ");
for (i = 0; i<size; i++)
printf("%d ", ar[i]);
return 0;
}
void rReverseAr(int ar[], int size) {
int start = 0, end = size - 1, temp;
if (start < end) {
temp = ar[start];
ar[start] = ar[end];
ar[end] = temp;
start++;
end--;
rReverseAr(ar, size - 1);
}
}
The expected output should be when user entered 1 2 3 and it supposed to return 3 2 1. However, with these code, the output that I am getting is 2 3 1.
Any ideas?
Your code is almost right. The only problem is that instead of "shrinking" the array from both sides, you shrink it only from the back.
The recursive invocation should look like this:
rReverseAr(ar + 1, size - 2);
You do not need to increment start or decrement end, because their values are not used after modification.
A Simple way :
#include<stdio.h>
using namespace std;
void revs(int i, int n, int arr[])
{
if(i==n)
{
return ;
}
else
{
revs(i+1, n, arr);
printf("%d ", arr[i]);
}
}
int main()
{
int i, n, arr[10];
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%d", &arr[i]);
}
revs(0, n, arr);
return 0;
}
Iterate array with recursion in C : link
What you are doing is to exchange values of the 1st and last elements and do the recursion.
Every time you should move your address to the next element as the starter for the next array exchange.
A possible way:
void rReverseAr(int ar[], int size){
int buffer=ar[0];
ar[0] = ar[size-1];
ar[size-1] = buffer;
if ((size!=2)&&(size!=1)) rReverseAr(ar+1,size-2);
}

Resources