Error in sum of array using recursion (Compilation and runtime) - c++

I was asked to do sum of numbers in an array using recursion where sample input would be provided and the compiler gave me the following errors (note, I tried three ways and got the corresponding errors). Can someone please explain to me what I was doing wrong here?
Error for Code 1
In file included from Runner.cpp:2:0:
Solution.h: In function 'int sum(int*, int)':
Solution.h:7:32: error: invalid conversion from 'int' to 'int*' [-fpermissive]
totalsum = totalsum + sum(n+1,n-1);
^
Solution.h:1:5: note: initializing argument 1 of 'int sum(int*, int)'
int sum(int input[], int n) {
^
Error for code 2
Solution.h: In function 'int sum(int*, int)':
Solution.h:5:24: error: invalid conversion from 'int' to 'int*' [-fpermissive]
return input[0] + sum(n+1,n-1);
^
Solution.h:1:5: note: initializing argument 1 of 'int sum(int*, int)'
int sum(int input[], int n) {
^
Error for code 3
Runtime error
Code 1
int sum(int input[], int n) {
if (n<=0)
{
return 0;
};
int totalsum;
totalsum = totalsum + sum(n+1,n-1);
return totalsum;
}
Code 2
if (n<=0)
return 0;
return input[0] + sum(n+1,n-1);
Code 3
if (n <= 0)
return 0;
return (sum(input, n +1) + input[n - 1]);

In this function implementation
int sum(int input[], int n) {
if (n<=0)
{
return 0;
};
int totalsum;
totalsum = totalsum + `sum(n+1,n-1)`;
return totalsum;
}
the first parameter declared like int input[] has the type int *. However instead of the array you are passing the integer n + 1 as an argument in the recursive call
sum(n+1,n-1)
The same problem exists in this code snippet
if (n<=0)
return 0;
return input[0] + sum(n+1,n-1);
In the second code snippet it seems there is access memory beyond the array
return (sum(input, n +1) + input[n - 1]);
^^^^
And moreover the call has an infinite recursion because the second argument is always increased: n + 1.
The function can be written like
long long int sum( const int a[], size_t n )
{
return n == 0 ? 0 : a[0] + sum( a + 1, n - 1 );
}
Another approach is the following
long long int sum( const int a[], size_t n )
{
return n == 0 ? 0 :
( n == 1 : a[0] ? sum( a, n / 2 ) + sum( a + n / 2, n - n / 2 ) );
}
Here is a demonstrative program
#include <iostream>
long long int sum( const int a[], size_t n )
{
return n == 0 ? 0
: ( n == 1 ? a[0] : sum( a, n / 2 ) + sum( a + n / 2, n - n / 2 ) );
}
int main()
{
int a[] = { 1, 2,3, 4,5, 6, 7, 8, 9, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
std::cout << sum( a, N ) << '\n';
return 0;
}
Its output is
55

For error for code 1, you are using an integer variable where it is expecting an array. To correct this, you would need to make n an index of some array. so the call would be something like sum(index[n+1], n-1) . Reason being is that arrays are pointers, pointers are arrays. so unless you have a pointer to an int variable, it will not work.

Related

Can we add an integer to an array in c++

#include <bits/stdc++.h>
using namespace std;
/*Prototype for utility functions */
void printArray(int arr[], int size);
void swap(int arr[], int fi, int si, int d);
void leftRotate(int arr[], int d, int n)
{
/* Return If number of elements to be rotated
is zero or equal to array size */
if(d == 0 || d == n)
return;
/*If number of elements to be rotated
is exactly half of array size */
if(n - d == d)
{
swap(arr, 0, n - d, d);
return;
}
/* If A is shorter*/
if(d < n - d)
{
swap(arr, 0, n - d, d);
leftRotate(arr, d, n - d);
}
else /* If B is shorter*/
{
swap(arr, 0, d, n - d);
leftRotate(arr + n - d, 2 * d - n, d); /*This is tricky*/
}
}
/*UTILITY FUNCTIONS*/
/* function to print an array */
void printArray(int arr[], int size)
{
int i;
for(i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
/*This function swaps d elements starting at index fi
with d elements starting at index si */
void swap(int arr[], int fi, int si, int d)
{
int i, temp;
for(i = 0; i < d; i++)
{
temp = arr[fi + i];
arr[fi + i] = arr[si + i];
arr[si + i] = temp;
}
}
// Driver Code
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
leftRotate(arr, 2, 7);
printArray(arr, 7);
return 0;
}
// This code is contributed by Rath Bhupendra
I found this code on the geek for geeks website. The code is used to rotate the elements of an array. It is mentioned as block swap algorithm in the website, my questions are:
Can we add integers to an array in c++ as given in the else part of the left rotate function while passing the arguments (arr+n-d)?
How can we add integers to an array?
I tried adding an integer to an array in an online compiler and it didn't work. But the above code works perfectly giving the desired output 34567.
The link to the website is https://www.geeksforgeeks.org/block-swap-algorithm-for-array-rotation/.
Can we add integers to an array in c++ as given in the else part of the left rotate function while passing the arguments (arr+n-d)?
How can we add integers to an array?
The answer is you can't, and that's not what's happening here.
int arr[] argument decays to a pointer to the first element of the array. It's the same as having int* arr so what you are doing in arr + n - d is simple pointer arithmetic.
The pointer will be moved n - d positions relative to the position it's at before the expression is evaluated.
Supposing the result of n - d is 4, and arr is pointing to the beginning of the array passed as an argument, that is to &arr[0] (in array notation) or arr + 0 (in pointer notation), which is where it's pointing to in its inicial state, you'll have arr + 4 or &arr[4], after the evaluation, the expression provides access to the address of index 4 (the 5th element of the array). To access the value within that address you'd use *(arr + 4) or arr[4].
On a side note I wouldn't advise the use of geeksforgeeks.com to learn C++, or any other language, for that matter, this should be done by reading a good book.
A function parameter having an array type is adjusted by the compiler to pointer to the array element type. That is these two function declarations are equivalent and declare the same one function.
void leftRotate(int arr[], int d, int n);
and
void leftRotate(int *arr, int d, int n);
You even may write for example
void leftRotate(int arr[100], int d, int n);
void leftRotate(int arr[10], int d, int n);
void leftRotate(int arr[1], int d, int n);
Again these declarations declare the function
void leftRotate(int *arr, int d, int n);
So within the function this expression
arr + n - d
uses the pointer arithmetic applied to the pointer arr.
For example the expression arr + 0 is equivalent to arr and points to the first element of the array. The expression arr + n points to the n-th element of the array.
Here is a demonstrative program where there is used the pointer arithmetic to output elements of an array in a loop.
#include <iostream>
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
std::cout << *( a + i ) << ' ';
}
std::cout << '\n';
return 0;
}
The program output is
1 2 3 4 5
In the expression *( a + i ) the array designator a is implicitly converted to pointer to its first element.
Here is one more demonstrative program that shows that a function parameter having an array type is adjusted by the compiler to pointer to the array element type.
#include <iostream>
#include <iomanip>
#include <type_traits>
const size_t N = 100;
void f( int a[N] )
{
std::cout << "\nin function\n";
std::cout << "sizeof( a ) = " << sizeof( a ) << '\n';
std::cout << "a is a pointer " << std::boolalpha <<std:: is_same<decltype( a ), int *>::value << '\n';
}
int main()
{
int a[N];
std::cout << "In main\n";
std::cout << "sizeof( a ) = " << sizeof( a ) << '\n';
std::cout << "a is an array " << std::boolalpha <<std:: is_same<decltype( a ), int [N]>::value << '\n';
f( a );
return 0;
}
The program output is
In main
sizeof( a ) = 400
a is an array true
in function
sizeof( a ) = 8
a is a pointer true

C++ adding two array items and other errors on run

When I compile and run this program, I get different errors mostly regarding the calling of the function and the sum of arrays - I have tried fixing them myself but whenever I fix one problem I seem to never be able to fix them all as more come in then leave.
/*
Even Fibonacci numbers
Problem 2
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
*/
#include <iostream>
#include <string>
using namespace std;
int increaseArray(int array, int currentPointer, int maxNumber, int arraySize, bool stop, int total);
int main () {
int arraySize = 2;
int maxNumber = 4000000;
int currentPointer = 1;
int array[2] = {1, 2};
int total = 0;
bool stop = false;
while (not stop) {
increaseArray(array, currentPointer, maxNumber, arraySize, stop, total);
}
}
int increaseArray(int array, int currentPointer, int maxNumber, int arraySize, bool stop, int total) {
int newValue = array[currentPointer - 1] + array[currentPointer - 2];
while (newValue < maxNumber) {
arraySize++;
int *array = new int[arraySize];
array[arraySize] = newValue;
if (newValue % 2 == 0) {
total += newValue;
increaseArray(array, currentPointer, maxNumber, arraySize, stop, total);
}
stop = true;
return total;
}
};
Here are the errors that I am getting:-
error: no matching function for call to 'increaseArray'
increaseArray(array, currentPointer, maxNumber, arraySize, stop, total);
^~~
note: candidate function not viable: no known conversion from 'int [2]' to 'int' for 1st argument
int increaseArray(int array, int currentPointer, int maxNumber, int arraySize, bool stop, int total);
^
error: subscripted value is not an array, pointer, or vector
int newValue = array[currentPointer - 1] + array[currentPointer - 2];
~^~~~~
error: subscripted value is not an array, pointer, or vector
int newValue = array[currentPointer - 1] + array[currentPointer - 2];
~^~~~~
error: no matching function for call to 'increaseArray'
increaseArray(array, currentPointer, maxNumber, arraySize, stop, total);
^~~
note: candidate function not viable: no known conversion from 'int ' to 'int' for 1st argument; dereference the argument with
int increaseArray(int array, int currentPointer, int maxNumber, int arraySize, bool stop, int total) {
^
4 errors generated.
The problem is in the declaration of increaseArray function.
You want to pass as an argument a whole array, but you declare that the first argument is just an integer.
One solution to the problem would be:
int increaseArray(int * array,....).
I would strongly recommend to learn more about passing arrays to functions.
A good place to start would be: https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
I hope that helps!

Can we add an array variable to integer?

This is a program to find median of two sorted arrays.
A divide and conquer based efficient solution to find median of two sorted arrays of same size.
#include<bits/stdc++.h>
using namespace std;
int median(int [], int); /* to get median of a sorted array */
/* This function returns median of ar1[] and ar2[].
Assumptions in this function:
Both ar1[] and ar2[] are sorted arrays
Both have n elements */
int getMedian(int ar1[], int ar2[], int n)
{
/* return -1 for invalid input */
if (n <= 0)
return -1;
if (n == 1)
return (ar1[0] + ar2[0])/2;
if (n == 2)
return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2;
int m1 = median(ar1, n); /* get the median of the first array */
int m2 = median(ar2, n); /* get the median of the second array */
/* If medians are equal then return either m1 or m2 */
if (m1 == m2)
return m1;
/* if m1 < m2 then median must exist in ar1[m1....] and
ar2[....m2] */
if (m1 < m2)
{
if (n % 2 == 0)
{
return getMedian(ar1 + n/2 - 1, ar2, n - n/2 +1);
}
return getMedian(ar1 + n/2, ar2, n - n/2);
}
/* if m1 > m2 then median must exist in ar1[....m1] and
ar2[m2...] */
if (n % 2 == 0)
return getMedian(ar2 + n/2 - 1, ar1, n - n/2 + 1);
return getMedian(ar2 + n/2, ar1, n - n/2);
}
/* Function to get median of a sorted array */
int median(int arr[], int n)
{
if (n%2 == 0)
return (arr[n/2] + arr[n/2-1])/2;
else
return arr[n/2];
}
/* Driver program to test above function */
int main()
{
int ar1[] = {1, 2, 3, 6};
int ar2[] = {4, 6, 8, 10};
int n1 = sizeof(ar1)/sizeof(ar1[0]);
int n2 = sizeof(ar2)/sizeof(ar2[0]);
if (n1 == n2)
printf("Median is %d", getMedian(ar1, ar2, n1));
else
printf("Doesn't work for arrays of unequal size");
return 0;
}
My question is how can I add a array variable to an integer. I means whether it is referring to memory when we do like this (ar1 + n/2 - 1) here in the getmedian function call ?
In expressions an array designator is implicitly converted to the pointer to its first element. Adding an integer to a pointer you will get again a pointer. It is so called the pointer arithmetic.
Thus for example if you have an array
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
then expression
a + N / 2
will point to the sixth element of the array.
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%p: %d\n", a + i, *( a + i ) );
return 0;
}
Its output might look like
0xbfd3d9c8: 0
0xbfd3d9cc: 1
0xbfd3d9d0: 2
0xbfd3d9d4: 3
0xbfd3d9d8: 4
0xbfd3d9dc: 5
0xbfd3d9e0: 6
0xbfd3d9e4: 7
0xbfd3d9e8: 8
0xbfd3d9ec: 9
Also a function parameter declared like an array is also adjusted to pointer. So for example these function declarations
int median(int a[100], int n);
int median(int a[10], int n);
int median(int a[], int n);
int median(int *a, int n);
are equivalent and declare the same one function.

Is there limitation for recursion?

I am testing recursion, however when I have an array with more than 150000 elements segmentation error occurs. What can be the problem?
#include <iostream>
using namespace std;
void init ( float a[] , long int n );
float standard ( float a[] , long int n , long int i );
int main()
{
long int n = 1000000;
float *a = new float[n];
init ( a , n );
cout.precision ( 30 );
cout << "I got here." << endl;
cout << "Standard sum= " << standard ( a , 0 , n - 1 ) << endl;
delete [] a;
return 0;
}
void init ( float a[] , long int n )
{
for (long int i = 0 ; i < n ; i++ )
{
a[i] = 1. / ( i + 1. );
}
}
float standard ( float a[] , long int i , long int n )
{
if ( i <= n )
return a[i] + standard ( a , i + 1 , n );
return 0;
}
As an expansion to MicroVirus' correct answer, here is an example of tail recursive version of your algorithm:
float standard_recursion(float* a, long i, long n, long result) {
if(i > n)
return result;
return standard_recursion(a, i + 1, n, result + a[i]);
}
float standard(float* a, long i, long n ) {
return standard_recursion(a, i, n, 0);
}
This should run if the compiler does tail call optimization (I tested on g++ -O2). However, since the functionality depends on the compiler optimization, I would recommend to avoid deep recursion entirely and opt for iterative solution.
You are most likely running out of stack space in your recursive function standard, which recurses with a depth of n, and tail-call optimisation is probably not enabled here.
So, to answer the question in your title: Yes, there is a limit to recursion, and usually it's the available stack space.
Probably you are out of memory on heap. Also if you got 16bit int, there could be a problem with iterations. Better use int32_t i instead of int i. Same with n.

Counting number of digits in an integer through recursion

My code is following:
/counting number of digits in an integer
#include <iostream>
using namespace std;
int countNum(int n,int d){
if(n==0)
return d;
else
return (n/10,d++);
}
int main(){
int n;
int d;
cout<<"Enter number"<<endl;
cin>>n;
int x=countNum();
cout<<x;
return 0;
}
i cannot figure out the error,it says that
: too few arguments to function `int countNum(int, int)'
what is issue?
Because you declared the function to take two arguments:
int countNum(int n,int d){
and you are passing none in:
int x = countNum();
You probably meant to call it like this, instead:
int x = countNum(n, d);
Also this:
return (n/10,d++);
should probably be this:
return countNum(n/10,d++);
Also you are not initializing your n and d variables:
int n;
int d;
Finally you don't need the d argument at all. Here's a better version:
int countNum(int n){
return (n >= 10)
? 1 + countNum(n/10)
: 1;
}
and here's the working example.
int x=countNum(); the caller function should pass actual arguments to calling function. You have defined function countNum(int, int) which means it will receive two ints as arguments from the calling function, so the caller should pass them which are missing in your case. Thats the reason of error too few arguments.
Your code here:
int x=countNum();
countNum needs to be called with two integers. eg
int x=countNum(n, d);
Because you haven't passed parameters to the countNum function. Use it like int x=countNum(n,d);
Assuming this is not for an assignment, there are better ways to do this (just a couple of examples):
Convert to string
unsigned int count_digits(unsigned int n)
{
std::string sValue = std::to_string(n);
return sValue.length();
}
Loop
unsigned int count_digits(unsigned int n)
{
unsigned int cnt = 1;
if (n > 0)
{
for (n = n/10; n > 0; n /= 10, ++cnt);
}
return cnt;
}
Tail End Recursion
unsigned int count_digits(unsigned int n, unsigned int cnt = 1)
{
if (n < 10)
return cnt;
else
return count_digits(n / 10, cnt + 1);
}
Note: With tail-end recursion optimizations turned on, your compiler will transform this into a loop for you - preventing the unnecessary flooding of the call stack.
Change it to:
int x=countNum(n,0);
You don't need to pass d in, you can just pass 0 as the seed.
Also change countNum to this:
int countNum(int n,int d){
if(n==0)
return d;
else
return coutNum(n/10,d+1); // NOTE: This is the recursive bit!
}
#include <iostream>
using namespace std;
int countNum(int n,int d){
if(n<10)
return d;
else
return countNum(n/10, d+1);
}
int main(){
int n;
cout<<"Enter number"<<endl;
cin>>n;
int x=countNum(n, 1);
cout<<x;
return 0;
}
Your function is written incorrectly. For example it is not clear why it has two parameters or where it calls recursively itself.
I would write it the following way
int countNum( int n )
{
return 1 + ( ( n /= 10 ) ? countNum( n ) : 0 );
}
Or even it would be better to define it as
constexpr int countNum( int n )
{
return 1 + ( ( n / 10 ) ? countNum( n/10 ) : 0 );
}