storing values in string during recursion - c++

I want to store the values produced by a recursive function in a string, but I am not sure how to keep after each iteration of the loop. Im not necessarily looking for you to solve it particular to the attached code, but I figured it would give it some context. Simply commenting resources where I can learn this is, of course, welcome.
Thanks
int HailstoneNumbers(int N)
{
vector <char> sequence;
static int c;
cout << N << " ";
if (N == 1 && c == 0) {
// N is initially 1.
return c;
}
else if (N == 1 && c != 0) {
// N is reduced to 1.
c++;
return c;
}
else if (N % 2 == 0) {
// If N is Even.
c++;
HailstoneNumbers(N / 2);
}
else if (N % 2 != 0) {
// N is Odd.
c++;
HailstoneNumbers(3 * N + 1);
}
}

If you want to store N values, you can store them in a vector as follows
int HailstoneNumbers(int N, vector<int>& sequence)
{
int c;
sequence.push_back(N);
if (N == 1 && c == 0) {
// N is initially 1.
return c;
}
else if (N == 1 && c != 0) {
// N is reduced to 1.
c++;
return c;
}
else if (N % 2 == 0) {
// If N is Even.
c++;
HailstoneNumbers(N / 2, sequence);
}
else if (N % 2 != 0) {
// N is Odd.
c++;
HailstoneNumbers(3 * N + 1, sequence);
}
}
declare a vector before calling your function as vector<int> sequence; then call your function using your N and this vector

Related

How can I reduce the time complexity of the following block of code?

I am taking 1 to n digits and finding count of numbers that are divisible by a or b but not divisible by both.
I want to reduce time complexity of this block by some logical change.
cin >> n >> a >> b >> k;
for(int i = 1; i <= n; i++) {
if(i % a == 0 && i % b==0) {
count++;
} else if(i % b == 0 && i % a != 0) {
count++;
}
}
Calculate the count of numbers divisible by a, add it to the count of numbers divisible by b, subtract it with twice the count of numbers divisible by the lcm (lowest common multiple) of a,b.
Time complexity: O(log(min(a,b)))
Because to calculate Lowest common multiple you calculate gcd (Greatest common divisor) which can be calculated in O(log(min(a,b)))
Note: If you include bits/stdc++.h, you can use the inbuilt function to calculate gcd: __gcd(int , int )
int lcm(int a, int b) {
return (a * b)/__gcd(a,b);
}
cin>>n>>a>>b>>k;
int divisible_by_a = n / a;
int divisible_by_b = n / b;
int divisible_by_both = n / lcm(a,b);
ans = divisible_by_a + divisible_by_b - 2*divisible_by_both;
It seems to me that your code don't work as you describe: it counts for every number divisible by b. You should check if i is multiple of a or b
if (i % a == 0 && i % b != 0) {...
} else if (i % a != 0 && i % b == 0) {...
}
I also suggest to you a different approach: find multiples of a and b untill you reach n and count that numbers. remove same numers in lists from the sum (better if you do that before the final sum)
Before optimizing it, make sure it works first.
Right now, you're checking if a number is divisible by only b or by both a and b. To make it a or b but not both, you need to switch i % b==0 to i % b!=0 in the first condition:
for(int i = 1; i <= n; i++) {
if(i % a == 0 && i % b!=0) {
count++;
} else if(i % b == 0 && i % a != 0) {
count++;
}
}
One small thing you can do to speed things up is to do the divisibility check just once each and save the result instead of twice. Then you can use a single XOR for the final result.
for(int i = 1; i <= n; i++) {
int div_a = (i % a == 0);
int div_b = (i % b == 0);
if (a ^ b) {
count++;
}
}
Let's start with this:
temp = a;
while(temp < n) {
if(temp%b != 0) {
count++;
}
temp += a;
}
temp = b;
while(temp < n) {
if(temp%a != 0) {
count++;
}
temp += b;
}
Next, consider some cheats. If a%b == 0 then any number divisible by a will also be divisible by b; and similar for b%a == 0. In both cases the count must be zero.
If a == 0 then no number is divisible by a; and similar for b == 0; and if both a and b are zero then the count must be zero.
Finally; don't forget that (in C) the behavior of x%0 is undefined and you need to guard against that.
Combining all of the above you get something like:
if( (a == 0) && (b == 0) ) {
return 0;
}
if( (a != 0) && (b != 0) ) {
if( (a%b == 0) || (b%a == 0) ) {
return 0;
}
}
count = 0;
if(a != 0) {
temp = a;
while(temp < n) {
if(temp%b != 0) {
count++;
}
temp += a;
}
}
if(b != 0) {
temp = b;
while(temp < n) {
if(temp%a != 0) {
count++;
}
temp += b;
}
}
return count;
Next round of cheats:
If n <= 1 then the count must be zero.
If a == 1 or a == -1 then all numbers are divisible by a.
If b == 1 or b == -1 then all numbers are divisible by b.
To deal with these I'd move to "nested switch" to minimise the number of branches, like:
switch(a) {
case 0:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
case -1:
case 1:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
default:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
}

Recursions and functions c++

I have made a function and I am trying to make it recursive. Does anyone have any tips on how I can make this function recursive? I know recursive means to use the function in the function itself.
int countEven(int n){
int evens = 0;
if(n <= 0) return 0; //base case
while(n > 0){
int digit = n%10; //get the last digit
if(digit%2 == 0){
evens = evens + 1;
}
n = n/10;
}
cout << evens;
}
int rec(int n)
{
int sum = 0;
if(n<=0)
return 0;
else if ((n%10)%2==0)
sum = rec(n/10)+1;
else
sum = rec(n/10);
return sum;
}
Maybe something like this :)
For counting the even digits of an integer base 10 you can simplify the function to the following
int countEven(int n)
{
if (n != 0) return !(n % 2) + countEven(n/10);
else return 0;
}
This expands as follows. Assume n = 258:
countEven(258) =
1 + countEven(25) =
1 + 0 + countEven(2) =
1 + 0 + 1 + countEven(0) = 2
Note that the statement !(n % 2) returns 1 if n is even and 0 if it's odd.
For shorter you can do the following:
int ce(int n) { return n ? !(n&1) + ce(n/10) : 0; }
using the ternary operator.
seems like you're trying to count the even digits in a number
int countEven(int n){
if(n == 0)
return 0; //base case
if (n<10)
return !(n%2);
return !(n%2)+countEven(n/10);
}
looks like a similar question i received from QC.
to make it recursive, you must have the function calling onto itself. Ask how you can make the the input simpler and have some sort of base so that the function doesn't break.
int countEven(int number) {
if (x <= 0) return 0;
if (x % 2 == 0) {
return countEven(number / 10) + 1;
}
return countEven(number / 10)
}

Counting total Paths from (0,0) to (n-1,n-1) in a n*n grid

I am using a simple backtracking algorithm to find all the paths but it does not give the right answer. I am not able to figure out the mistake. We can move up, down, left and right from a given position.
Int path(int a[][200],int n,int m,int r,int c)
{
if(n == r - 1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = path(a,n+1,m,r,c);
int y = path(a,n,m+1,r,c);
int u = path(a,n-1,m,r,c);
int v = path(a,n,m-1,r,c);
vis[n][m] = 0;
return (x+y+u+v);
}
}
To find the paths or count the paths are not exactly the same thing. I will assume you want to just count the paths (because the title of your question), and that you can only move right or move down.
For this you don't really need a matrix (representing the grid) as a parameter. The following is a simple (although not efficient) recursive solution that also will work for a n*m grid:
int countPaths(int m, int n) {
if (m == 0 || n == 0)
return 1;
return countPaths(m-1, n) + countPaths(m, n-1);
}
The mathematical solution for the general n*n grid is:
(2n choose n) = (2*n)!/(n!*n!)
Then, comparing results with the formula:
countPaths(1, 1) == 2 // (2*1)!/(1!*1!)=2
countPaths(2, 2) == 6 // (2*2)!/(2!*2!)=6
countPaths(3, 3) == 20 // (2*3)!/(3!*3!)=20
Your backtracking approach will give the same results, but with some considerations. For example, consider when n=2, you will need a 3x3 matrix (and in general a (n+1)x(n+1) matrix) to represent/explore (and mark with 1) all the paths for the 2x2 grid:
int countPaths(int a[][3],int n, int m, int r, int c) {
if(n == r-1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = countPaths(a,n+1,m,r,c);
int y = countPaths(a,n,m+1,r,c);
vis[n][m] = 0;
return (x+y);
}
}
Then:
countPaths(vis, 0, 0, 3, 3) == 6 // (2*2)!/(2!*2!)=6

Calculate the function F(n) with recursion

Read the topic that I do not know what it is saying:
The function F (n) determined on non-negative integers as follows:
F (0) = 1; F (1) = 1; F (2n) = f (n); F (2n + 1) = F (n) + F (n + 1)
Calculated F (n) by recursion.
and my code:
#include<iostream.h>
double TINH_F(int n)
{
if(n == 0)
{
return 0;
}
if(n == 1)
{
return 1;
}
return (F(n+1) - F(2*n+1));
}
This is obviously incorrect. A recursive function calls itself and includes a stopping condition:
#include<iostream.h>
double TINH_F(int n)
{
if(n == 0)
{
return 0;
}
if(n == 1)
{
return 1;
}
// Note the function name change
return (TINH_F(n+1) - TINH_F(2*n+1));
}
What should your function do if the integer passed in is negative? Will the recursion still work? Or should you throw an exception to indicate to callers that the contract is broken?
int f(int n)
{
if (n<0) return -1; // check if n is positive
if (n<=1) return 1; // we can catch the first two cases in a single condition
int half = n/2;
if (n % 2 == 0) return f(half); // if n is even
else return f(half) + f(half+1); // if n is odd
}
Your last case says
F (n) = F (n+1) + F(2 * n + 1), for all n > 1
If you read the definition carefully, this case is not mentioned anywhere.
I believe you're being tricked by the naming of the parameter - you need four cases.
Let's break it down:
F (0) = 1 (or 0 - your definition says 1, but the code says 0...)
F (1) = 1
F (2n) = F (n)
F (2n + 1) = F (n) + F (n + 1)
The first two cases are trivial.
The third case says that if the argument - let's call it m - is even, the result is F(m/2).
The fourth case says that if the argument m is odd, the result is F(m/2) + F(m/2 + 1).
(Confirming the arithmetic left as an exercise.)
In C++:
unsigned int TINH_F(unsigned int n)
{
if(n == 0)
{
return 1;
}
else if(n == 1)
{
return 1;
}
else if (n % 2 == 0)
{
return TINH_F(n / 2);
}
else
{
return TINH_F(n/2) + TINH_F(n/2 + 1);
}
}

C++ Recursion Segmentation Fault

#include <iostream>
using namespace std;
int findSumofOdds(int n);
int main()
{
int n = 88;
int x;
x = findSumofOdds(n);
cout << x << endl;
return 0;
}
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1);
return(findSumofOdds(n-1) + 1);
}
else
return 1;
}
Why isn't this recursion working? It tries to run and then crashes. Please let me know. My teacher said that it would work but doesn't.
When n is even, you are decrementing n by two. If it skips over n == 1, it will recurse until it causes a stack overflow. Since n starts out at 88, that's what's happening.
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1); // <== first decrement
return(findSumofOdds(n-1) + 1); // <== second decrement
}
else
return 1;
}
Also, you seem to be counting the number of odd numbers, not adding them. My guess is that you actually want something like:
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
return(findSumofOdds(n - 1));
return(findSumofOdds(n-1) + n); // or + 1 to just count
}
else
return 1;
}
If you want to practice recursion, that's fine. But there's a much simpler way to write a function to sum the odd numbers up to and including n:
int fundSumofOdds(int n) {
n = (n + 1) / 2;
return n * n;
}
This is because there's a general formula:
1 + 3 + 5 + ... + 2n-1 = n2
You have to make it
if (n > 1)
Consider n = 2 here
if (n != 1)
{
if( n % 2 == 0) // Yes
n = (n - 1); // n = 1
return(findSumofOdds(n-1) + 1); // n = 0 <-- will not stop.
and change this too. right now it is just counting the number of odd numbers. You need to sum them.
return(n + findSumofOdds(n - 1));
}
else
return 0;
If you print n in findSumofOdds you can see what is happening -- n becomes negative and you get infinite recursion. If your program doesn't crash earlier, you can get integer overflow (when n goes below the minimum value for int) which yields undefined behavior.
To correct this you can do this:
int findSumofOdds(int n)
{
if(n < 1)
{
return 0;
}
if(n % 2 == 0)
{
return findSumofOdds(n - 1) + 1;
}
return findSumofOdds(n - 2) + 1;
}
You can subtract 2 from n in the last statement, because you only need odd numbers and you know that n can't be even at that point (because of if(n % 2 == 0)).
Also, do you need to find the sum of all odd numbers smaller than n (e.g. 4 (== 1 + 3) for n=5) or do you just need to count them (which is what you are doing now)?
If you want to sum the numbers, you have do add n instead of 1 when returning.