Print accumulated sums in C++ in a recursive function - c++

So I have this function and these global variables.
int recurs=0;
std::string sign="";
void count2(int k, std::vector<int> d, int total, int temp, bool flag, unsigned short int pos){
std::string mas="+";
std::string menos="-";
if(pos==(d.size())){
total+=temp;
if(total==k){
result++;
std::cout << sign << "=" << k<<std::endl;
str="";
}
recurs++;
return;
}
//Sum sign.
sign=sign.substr(0,sign.size()-recurs*2);
sign.append(mas+=std::to_string(d[pos]));
count2(k,d,total+temp,+d[pos],true,pos+1);
//Rest sign
sign=sign.substr(0,sign.size()-recurs*2);
sign.append(menos+=std::to_string(d[pos]));
count2(k,d,total+temp,-d[pos],false,pos+1);
//Append digit
if(flag==true)
count2(k,d,total,10*temp-d[pos],true,pos+1);
else
count2(k,d,total,+10*temp+d[pos],false,pos+1);
}
The function is called like this:
count2(6,{1,2,3,3,3},0,0,true,0);
What it does: Given a vector v, it makes combinations of sums and substractions and numbers and everytime that this combination equals the first parameter, a global variable result is increased. For example, count2(6,{1,2,3,3,3},0,0,true,0); would make result be 5. Since there is 5 ways to sum/sub 6 with those numbers, e.g.: 1+2+3+3-3 1+2-3+3+3 and some others. It works perfectly. Also, the variable string str is not used.
What is wrong? Nothing, but I'd like to see which these combinations are. I'd like the function to print thinks like:
1+2+3+3-3
1+2-3+3+3
-1-2+3+3+3
1+2+3-3+3
What is the question? I'd like to know how to correctly print the operatins that make total be equal to k.
If you were to run this code in ideone, it would print: YES, This is my actual outcome. But is not correct since there's no sum such as +3 or +3+3+3+3+3+3+....
+1+2+3+3-3=6
+3=6
+3-3+3-3-3+3+3=6
+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-1+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3=6
+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-1+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3=6
The correct outcome could look like:
1+2+3+3-3
1+2+3-3+3
1+2-3+3+3
-1-2+3+3+3
Question answered!

If you don't mind me changing the function signature a little bit, may I suggest the following?
int recurs = 0;
void count2(int k, std::vector<int> d, int total = 0, std::string temp = "", unsigned short pos = 0)
{
if(pos == d.size())
{
//test total number
if(total == k)
{
std::cout << temp <<"=" << k << std::endl;
recurs++;
}
}
else
{
//test each operator on next number in sequence
count2(k, d, total + d[pos], temp + ((pos) ? "+":"") + std::to_string(d[pos]), pos + 1);
count2(k, d, total - d[pos], temp + "-" + std::to_string(d[pos]), pos + 1);
}
}
The conditional operator will remove the '+' sign from the beginning. Default values make the function easier to call from main or wherever. By sending temp as a string, it is easier to keep track of the final equation, as well as removing it as a global variable. It also removes the need for your bool flag variable. Last, total is updated in the function call to remove clutter from the function body.

So finally count2 looks like this:
void count2(int k, std::vector<int> d, int total, int temp, bool flag, unsigned short int pos, std::vector<std::string> s){
//std::cout << temp << " ";
if(pos==(d.size())){
total+=temp;
if(total==k){
result++;
for(unsigned short int i=0;i<d.size();i++){
std::cout << s[i] << d[i];
}
std::cout << "=" << k <<"\n";
}
return;
}
s[pos]="+";
count2(k,d,total+temp,+d[pos],true,pos+1,s);
//put a - sign in pos
s[pos]="-";
count2(k,d,total+temp,-d[pos],false,pos+1,s);
if(pos==0) return;
//Append digit
if(flag==true){
s[pos]="";
//std::cout << "<0 " << 10*temp-d[pos] << " ";
count2(k,d,total,(10*temp-d[pos]),true,pos+1,s);
}
else{
s[pos]="";
//std::cout << ">0" << 10*temp+d[pos] << " ";
count2(k,d,total,10*temp+d[pos],false,pos+1,s);
}
}
You can see instead of using a string variable, I'm using a string vector, which makes it suitable for the recursion call.
Give it a try on ideone.com

Related

Changing function argument to global variable causes unexpected results

I'm solving a backtracking problem. I have to construct a permutation of length n in such a way that the sum of each adjacent elements are prime. The permutation is circular, the last element is adjacent to first element. Note that all valid permutations should start with 1.
void recurse(int i, int prev, int n, vector<int> prime_ring) {
if (i == n) {
prime_ring.insert(prime_ring.begin(), 1);
if (!is_prime[prime_ring.back() + 1])
return;
for (auto data : prime_ring)
cout << data << " ";
cout << "\n";
prime_ring.clear();
return;
}
for (int next = 2; next <= n; next++) {
if (!seen[next] && is_prime[prev + next]) {
prime_ring.push_back(next);
seen[next] = true;
recurse(i + 1, next, n, prime_ring);
seen[next] = false;
prime_ring.pop_back();
}
}
}
The above code generates the wanted permutations correctly. For example for n = 4. Permutations should be
1 2 3 4
1 4 3 2
void recurse(int i, int prev, int n) {
if (i == n) {
prime_ring.insert(prime_ring.begin(), 1);
if (!is_prime[prime_ring.back() + 1])
return;
for (auto data : prime_ring)
cout << data << " ";
cout << "\n";
prime_ring.clear();
return;
}
for (int next = 2; next <= n; next++) {
if (!seen[next] && is_prime[prev + next]) {
prime_ring.push_back(next);
seen[next] = true;
recurse(i + 1, next, n);
seen[next] = false;
prime_ring.pop_back();
}
}
}
Changing prime_ring to a global vector, results in runtime error. This problem happened to me many times, I failed to realise what's wrong. I'm not aware of the difference between global vector vs function argument vector.
I'm not aware of the difference between global vector vs function argument vector.
The difference is that when you pass a vector as a parameter, the vector is copied. On the other hand when you use a global variable, there is only one `vector.
The solution here is to not use a global variable since you have a working function.
Suppose you are on the line
recurse(i + 1, next, n);
where i == n - 1
Suppose when you go into the recurse function, is_prime[prime_ring.back() + 1] is true.
Then you call prime_ring.clear();, and returns.
Afterwards, you call prime_ring.pop_back();
What happens if you try to pop_back() from an empty vector? Well, bad things can happen (namely, Undefined Behaviour)

Recursive function that returns a sum of all elements in a vector

I am confused on how to get this function to add the last element in the vector. I cannot modify the functions parameters.
long vectorSum(const std::vector<int>& data, unsigned int position)
{
if (position == data.size()-1)
{
return 0;
}
else
{
return (vectorSum(data, position+1) + data[position]);
}
}
int main()
{
//vectorSum test
std::vector<int> data = { 1,2,3,4,5};
unsigned int pos = 0;
std::cout << "expected: 15, " << "actual: " << vectorSum(data, pos) << std::endl;
}
when you stop at data.size() -1 you are returning 0 for vectorSum(data, data.size()-1) without counting the value of the last entry
long vectorSum(const std::vector<int>& data, unsigned int position)
{
if (position == data.size()) // You were stopping early
{
return 0;
}
else
{
return (vectorSum(data, position+1) + data[position]);
}
}
int main()
{
//vectorSum test
std::vector<int> data = { 1,2,3,4,5};
unsigned int pos = 0;
std::cout << "expected: 15, " << "actual: " << vectorSum(data, pos) << std::endl;
}
When you're looking at the last element, you have this condition:
if (position == data.size()-1)
At this point, position is 4, and data.size() is 5. So the condition matches and the recursion ends.
You need to change the == to >, or drop the -1
There are always two parts to a recursive function: a stop condition and a recursion. A simple stop condition here is: when there are no elements in the vector, the sum is 0. The recursion is: the sum of the elements of a non-empty vector is the value of its first element plus the sum of the remaining elements. In code, the stop condition looks like this:
if (position == data.size())
return 0;
In code, the recursion looks like this:
else
return data[position] + vectorSum(data, position + 1);
A slightly more sophisticated stop condition would be: when there is exactly one element in the vector, the sum is the value of that element. In code:
if ( position == data.size() - 1)
return data[position];
Compared to the first one, this has one fewer levels of recursion. But it doesn't work for empty vectors. So pick your poison.
The problem with the original code is that its stop condition isn't implemented correctly. It inter-mixes these two stop conditions.

Using recursion to reverse an integer without trailing 0's in C++

I am stuck on how to omit trailing zeros, on a recursive call to reverse an integer. If you could just guide me to the right path I'd appreciate it. I am stuck and do not know how to do it. I have came this far, but am struggling to complete it. Thanks.
int main() {
int numToReverse;
cout << "Please enter in a number: " << endl;
cin >> numToReverse;
cout << reverseIntRecursion(numToReverse) << endl;
}
int reverseIntRecursion(int n) {
if (n < 10) //Base Case
return n;
else
cout << n % 10; // Prints out the last number
return reverseIntRecursion(n / 10); // General Case, Recursive Function
}
Maybe easiest way is parse int to string (array of chars) and print as array?
Here is some code that works just fine as long as you enter true for the second parameter:
int ReverseIntRecursion(int, bool);
int main(int argc, const char * argv[]) {
std::cout << ReverseIntRecursion(30400, true);
std::cout << std::endl;
return 0;
}
int ReverseIntRecursion(int N, bool FirstIter)
{
if (N < 10)
return N;
else if (N % 10 == 0 && FirstIter)
return ReverseIntRecursion(N/10, true);
else
std::cout << (N % 10);
return ReverseIntRecursion(N/10, false);
}
// prints 403
Your function isn't reversing an integer. It just prints digits in a reverse order.
This is why you are getting your trailing zeros problem. If you wrote a function which actually reversed the integer - your problem would disappear.
For example:
// Helper function for reversing an integer.
int reverseIntRecursionBase(int n, int& base) {
if (n < 10) // trivial case. If n consists of a single digit - reversed n is equal to n.
{
return n;
}
int result = reverseIntRecursionBase (n/10, base); // recurse until you hit a trivial case.
/*
The leftmost digits in the original number should be the
rightmost digits in the reversed number.
This code will be first executed, after trivial case has been hit:
e.g. given number 1234, this line will be first reached when n = 12; result = 1.
*/
base *= 10;
result = (n % 10)*base + result;
return result;
}
int reverseIntRecursion(int n) {
int base = 1;
return reverseIntRecursionBase (n, base);
}
Live demo.

C++ Program abruptly ends after cin

I am writing code to get the last digit of very large fibonacci numbers such as fib(239), etc.. I am using strings to store the numbers, grabbing the individual chars from end to beginning and then converting them to int and than storing the values back into another string. I have not been able to test what I have written because my program keeps abruptly closing after the std::cin >> n; line.
Here is what I have so far.
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using namespace std;
char get_fibonacci_last_digit_naive(int n) {
cout << "in func";
if (n <= 1)
return (char)n;
string previous= "0";
string current= "1";
for (int i = 0; i < n - 1; ++i) {
//long long tmp_previous = previous;
string tmp_previous= previous;
previous = current;
//current = tmp_previous + current; // could also use previous instead of current
// for with the current length of the longest of the two strings
//iterates from the end of the string to the front
for (int j=current.length(); j>=0; --j) {
// grab consectutive positions in the strings & convert them to integers
int t;
if (tmp_previous.at(j) == '\0')
// tmp_previous is empty use 0 instead
t=0;
else
t = stoi((string&)(tmp_previous.at(j)));
int c = stoi((string&)(current.at(j)));
// add the integers together
int valueAtJ= t+c;
// store the value into the equivalent position in current
current.at(j) = (char)(valueAtJ);
}
cout << current << ":current value";
}
return current[current.length()-1];
}
int main() {
int n;
std::cin >> n;
//char& c = get_fibonacci_last_digit_naive(n); // reference to a local variable returned WARNING
// http://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable
cout << "before call";
char c = get_fibonacci_last_digit_naive(n);
std::cout << c << '\n';
return 0;
}
The output is consistently the same. No matter what I enter for n, the output is always the same. This is the line I used to run the code and its output.
$ g++ -pipe -O2 -std=c++14 fibonacci_last_digit.cpp -lm
$ ./a.exe
10
There is a newline after the 10 and the 10 is what I input for n.
I appreciate any help. And happy holidays!
I'm posting this because your understanding of the problem seems to be taking a backseat to the choice of solution you're attempting to deploy. This is an example of an XY Problem, a problem where the choice of solution method and problems or roadblocks with its implementation obfuscates the actual problem you're trying to solve.
You are trying to calculate the final digit of the Nth Fibonacci number, where N could be gregarious. The basic understanding of the fibonacci sequence tells you that
fib(0) = 0
fib(1) = 1
fib(n) = fib(n-1) + fib(n-2), for all n larger than 1.
The iterative solution to solving fib(N) for its value would be:
unsigned fib(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value;
}
return current;
}
which is all well and good, but will obviously overflow once N causes an overflow of the storage capabilities of our chosen data type (in the above case, unsigned on most 32bit platforms will overflow after a mere 47 iterations).
But we don't need the actual fib values for each iteration. We only need the last digit of each iteration. Well, the base-10 last-digit is easy enough to get from any unsigned value. For our example, simply replace this:
current = value;
with this:
current = value % 10;
giving us a near-identical algorithm, but one that only "remembers" the last digit on each iteration:
unsigned fib_last_digit(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value % 10; // HERE
}
return current;
}
Now current always holds the single last digit of the prior sum, whether that prior sum exceeded 10 or not really isn't relevant to us. Once we have that the next iteration can use it to calculate the sum of two single positive digits, which cannot exceed 18, and again, we only need the last digit from that for the next iteration, etc.. This continues until we iterate however many times requested, and when finished, the final answer will present itself.
Validation
We know the first 20 or so fibonacci numbers look like this, run through fib:
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
11:89
12:144
13:233
14:377
15:610
16:987
17:1597
18:2584
19:4181
20:6765
Here's what we get when we run the algorithm through fib_last_digit instead:
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:3
8:1
9:4
10:5
11:9
12:4
13:3
14:7
15:0
16:7
17:7
18:4
19:1
20:5
That should give you a budding sense of confidence this is likely the algorithm you seek, and you can forego the string manipulations entirely.
Running this code on a Mac I get:
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string before callin funcAbort trap: 6
The most obvious problem with the code itself is in the following line:
for (int j=current.length(); j>=0; --j) {
Reasons:
If you are doing things like current.at(j), this will crash immediately. For example, the string "blah" has length 4, but there is no character at position 4.
The length of tmp_previous may be different from current. Calling tmp_previous.at(j) will crash when you go from 8 to 13 for example.
Additionally, as others have pointed out, if the the only thing you're interested in is the last digit, you do not need to go through the trouble of looping through every digit of every number. The trick here is to only remember the last digit of previous and current, so large numbers are never a problem and you don't have to do things like stoi.
As an alternative to a previous answer would be the string addition.
I tested it with the fibonacci number of 100000 and it works fine in just a few seconds. Working only with the last digit solves your problem for even larger numbers for sure. for all of you requiring the fibonacci number as well, here an algorithm:
std::string str_add(std::string a, std::string b)
{
// http://ideone.com/o7wLTt
size_t n = max(a.size(), b.size());
if (n > a.size()) {
a = string(n-a.size(), '0') + a;
}
if (n > b.size()) {
b = string(n-b.size(), '0') + b;
}
string result(n + 1, '0');
char carry = 0;
std::transform(a.rbegin(), a.rend(), b.rbegin(), result.rbegin(), [&carry](char x, char y)
{
char z = (x - '0') + (y - '0') + carry;
if (z > 9) {
carry = 1;
z -= 10;
} else {
carry = 0;
}
return z + '0';
});
result[0] = carry + '0';
n = result.find_first_not_of("0");
if (n != string::npos) {
result = result.substr(n);
}
return result;
}
std::string str_fib(size_t i)
{
std::string n1 = "0";
std::string n2 = "1";
for (size_t idx = 0; idx < i; ++idx) {
const std::string f = str_add(n1, n2);
n1 = n2;
n2 = f;
}
return n1;
}
int main() {
const size_t i = 100000;
const std::string f = str_fib(i);
if (!f.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << f[f.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
Try it with first calculating the fibonacci number and then converting the int to a std::string using std::to_string(). in the following you can extract the last digit using the [] operator on the last index.
int fib(int i)
{
int number = 1;
if (i > 2) {
number = fib(i - 1) + fib(i - 2);
}
return number;
}
int main() {
const int i = 10;
const int f = fib(i);
const std::string s = std::to_string(f);
if (!s.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << s[s.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
Avoid duplicates of the using keyword using.
Also consider switching from int to long or long long when your numbers get bigger. Since the fibonacci numbers are positive, also use unsigned.

Recursive Function Scanning String to Add ASCII

So I'm trying to figure out how to do this:
Write a recursive function that will sum all of the char's within a C String.
I'm a little rusty in doing this normally, but I finally got it to work with a normal for loop:
int countstr(string s)
{
int sum = 0;
if(s.length() == 0)
{
exit(0);
}
for (unsigned int i = 0; i < s.size(); i++)
{
sum += s[i];
}
return sum;
}
I can then go inside main and do this:
int main ()
{
cout << "This word adds up to " << countstr("HELLO") << " in ASCII " << endl;
}
and everything works as it should, counting and adding up the characters in the string via their ASCII numbers.
The problem I'm having is trying to figure out how this is typed up so it works recursively. I know I need to forgo the for loop in lieu of calling up the function itself, but I don't know what to use instead of the sum += s[i]; that I have going in my for loop. I've been looking around in the C string library, but I don't see anything that can replace the [i] that the for loop calls up. Does anyone know what I should be using to do this? I'm not looking for an answer in code, just need help in what I should be using to make this happen.
This is one of many ways to do it.
int reccountstr(string s, int i){
if(s.size() == i)
return (0 + s[i]);
else
return reccountstr(s, i + 1) + s[i];
}
And then in main you just call it with a zero initial argument.
cout << "This word adds up to " << reccountstr("HELLO", 0) << " in ASCII " << endl;
Skeleton could be like this:
int countlen(const char * str)
{
if (condition)
return 0;
else
return *str + countlen(str + 1);
}
The rest is up to you :)
int countString(char sample[], int i)
{
if(sample[i] == 0)
return 0;
else
return(1 + countString(sample, i+1));
}
This could be one solution, where if the current character read is not null (0, or '\0') it will return 1 + countString(sample, i + 1) where i is the current character index to be read.
Once it reaches null it returns 0. So for a character length of three, it will do 1 + 1 + 1 + 0. You can call the function with printf("%d\n", countString(yourStringName, 0)).
So your base case here is character[index] == empty
Your inductive case is 1 + function(stringName, index + 1), roughly speaking.
Also, this is a little outside the scope of your question, but you can also make this more efficient by avoiding constantly building up the stack. A way to do this is to create another variable inside the function that continuously accumulates the total count. For more info on this see this link on tail recursion:
http://c2.com/cgi/wiki?TailRecursion
More memory conservative version:
int countString(char sample[], int i, int total)
{
if(sample[i] == 0)
return total;
else
return countString(sample, i+1, ++total);
}
You can call this with printf("%d\n", countString(sample, 0, 0));