I've written a program for class where I need to recursively evaluate the extended euclid's algorithm for a and b, returning G, the greatest common divisor, as well as s and t from as+bt=gcd(a,b). I'm fairly certain I have the function written correctly but I am having issues with values being passed to and from the function. I haven't coded in a while and have only written pseudocode recently so I'm a little rusty.
For example, I have written when b=0, return (a, 1, 0), but when I input b as 0 I get returned (0, 0, 0) and cannot figure out why this is happening. Any help or guidance would be greatly appreciated.
#include <iostream>
using namespace std;
int ExtGCD (int a, int b)
{
int g, s, t, g1, s1, t1;
if (b == 0) {
return (a, 1, 0);
}
(g1, s1, t1) = ExtGCD(b, a%b);
g = g1;
s = s1;
t = s1 - ((a/b)*t1);
return (g, s, t);
}
int main(int argc, char* argv[])
{
int a,b, g2, s2, t2, temp;
cout << "Please input a: ";
cin >> a;
cout << "Please input b: ";
cin >> b;
if (b > a) {
temp = a; a = b; b = temp;
}
(g2, s2, t2) = ExtGCD (a, b);
cout << "G = "<< g2 << ", S = " << s2 << ", T = " << t2;
return 0;
}
C++11 introduces tuples, which allow you to write your code like this, with minimal modifications:
#include <iostream>
#include <tuple>
using namespace std;
std::tuple<int, int, int> ExtGCD (int a, int b)
{
int g, s, t, g1, s1, t1;
if (b == 0) {
return std::make_tuple(a, 1, 0);
}
std::tie(g1, s1, t1) = ExtGCD(b, a%b);
g = g1;
s = s1;
t = s1 - ((a/b)*t1);
return std::make_tuple(g, s, t);
}
int main(int argc, char* argv[])
{
int a,b, g2, s2, t2, temp;
cout << "Please input a: ";
cin >> a;
cout << "Please input b: ";
cin >> b;
if (b > a) {
temp = a; a = b; b = temp;
}
std::tie(g2, s2, t2) = ExtGCD (a, b);
cout << "G = "<< g2 << ", S = " << s2 << ", T = " << t2;
return 0;
}
See http://en.cppreference.com/w/cpp/utility/tuple/tie and http://en.cppreference.com/w/cpp/utility/tuple.
On a related note, you can also replace
if (b > a) {
temp = a; a = b; b = temp;
}
by
if (b > a)
std::swap(a, b);
or even by
std::tie(b, a) = std::minmax({a, b});
The C++ standard library provides many algorithmic facilities that should be learned to enjoy C++ to its full potential.
return (g, s, t);
doesn't do what you think it does. It's not possible to return multiple values from a function like that. Look up the comma operator if you want an explanation of what that code does.
There's a few different ways you could handle this. Perhaps the simplest is to return your values via references passed to the function. Like this
#include <iostream>
using namespace std;
void ExtGCD (int a, int b, int& g, int& s, int& t)
{
int g1, s1, t1;
if (b == 0) {
g = a;
s = 1;
t = 0;
return;
}
ExtGCD(b, a%b, g1, s1, t1);
g = g1;
s = s1;
t = s1 - ((a/b)*t1);
}
int main(int argc, char* argv[])
{
int a,b, g2, s2, t2, temp;
cout << "Please input a: ";
cin >> a;
cout << "Please input b: ";
cin >> b;
if (b > a) {
temp = a; a = b; b = temp;
}
ExtGCD (a, b, g2, s2, t2);
cout << "G = "<< g2 << ", S = " << s2 << ", T = " << t2;
return 0;
}
In this code g, s and t are references, which means assignments to them change the values of the variables bound to the references when the function is called.
You cannot return tuples like that.
In C++, the comma operator will throw out the stuff on the left. In your particular case, the "tuple" (a,b,c) is actually equal to just c. A more concrete example:
if (b == 0) {
return (a, 1, 0);
}
is actually the same as
if (b == 0) {
return 0;
}
To return multiple things at once, you'll have to use structs or classes.
Related
I have been asked by my teacher to solve this problem: "You get 3 different numbers as input, of different length, you have to determine the sum of the digits of all 3 numbers and also the product"
I solved it like this:
#include <bits/stdc++.h>
using namespace std;
int main () {
int a, b, c, S, P;
cin >> a >> b >> c;
S = 0;
P = 1;
while (a != 0) {
int c1 = a % 10;
S += c1;
P *= c1;
a /= 10;
}
while (b != 0) {
int c1 = b % 10;
S += c1;
P *= c1;
b /= 10;
}
while (c != 0) {
int c1 = c % 10;
S += c1;
P *= c1;
c /= 10;
}
cout << S << ' ' << P << endl;
}
My question is, is there a way to solve this more efficient?
You should bother not about the fastest way that does not make sense for such a simple program but about the correctness of the code and avoiding its duplication.
Your program is just incorrect.
For starters the user can interrupt the input. In this case at least one of the variables a, b, c will have indeterminate value. As a result the program will have undefined behavior.
Secondly, as you are using the signed int type when the user can enter negative numbers. In this case you will get an incorrect result because for example sum of digits can occur to be negative.
Thirdly, the user can enter 0 as a value of a number. In this case this number will be skipped in a while loop like this
while (a != 0) {
In this case you again will get an incorrect result because the product of digits can be not equal to zero though it must be equal to zero in this case.
The same while loops are duplicated. That is the program has a redundant code.
The program can be written the following way as it is shown in the demonstrative program below.
#include <iostream>
int main()
{
long long int a = 0, b = 0, c = 0;
std::cin >> a >>b >> c;
long long int sum = 0;
long long int product = 1;
for ( int num : { a, b, c } )
{
const long long int Base = 10;
do
{
long long int digit = num % Base;
if ( digit < 0 ) digit = -digit;
sum += digit;
if ( product ) product *= digit;
} while ( num /= Base );
}
std::cout << "sum = " << sum << '\n';
std::cout << "product = " << product << '\n';
return 0;
}
Move the repeated code to a separate function.
#include <iostream>
using namespace std;
void calc(int num, int &sum, int &product) {
do {
int c1 = num % 10;
sum += c1;
product *= c1;
num /= 10;
}
while (num != 0);
}
int main () {
int a, b, c, S = 0, P = 1;
if (cin >> a >> b >> c) {
calc(a, S, P);
calc(b, S, P);
calc(c, S, P);
cout << S << ' ' << P << endl;
}
return 0;
}
#include <iostream>
void isMax(int a, int b, int c, int d) {
int ans1, ans0, x;
a = !b, a = !c, a = !d,
b = !c, b = !d,
c = !d, c = !a;
if (a<b && b>c) { // ans0 starts
if (b > d) {
std::cout << b << std::endl;
}
else {
std::cout << d << std::endl;
}
}
else if (a < b && b < c) {
if (c > d) {
std::cout << c << std::endl;
}
else {
std::cout << d << std::endl;
}
}
//ans1
else if (a > b&& a > c) {
if (a > c&& a > d) {
std::cout << a << std::endl;
}
else if (a > c&& a < d) {
std::cout << d << std::endl;
}
else if (a<c && c>d) {
std::cout << c << std::endl;
}
else if (a < c && c < d) {
std::cout << d << std::endl;
}
else {
std::cout << "invalid numbers ahead." << std::endl;
}
}
std::cout << a << b << c << d << std::endl;
};
int main() {
isMax(3, 4, 6, 5);
return 0;
}
it kind of worked before i added
a = !b, a = !c, a = !d,
b = !c, b = !d,
c = !d, c = !a;
this part but did not work when i give the same values for a,b,c,d that`s why i added that part and now it does not work at all.
What is my mistake here ?
This image shows what i am trying to turn into code. Basically i`m trying to write a function that prints out the largest of four variables.
a != b; is true when a and b are different. What you wrote is a = !b; which is "assign to a the logically negated value of b".
I do not see how such assignment could make any sense here. That's why you get correct results without it and non-sense results when you add that assignments.
PS: Even if you "fix" it by writing a != b; the statement alone will have no effect. I suppose you want to return early or skip some of the later conditions when some input is equal.
From your schema, it should be:
void DisplayMax(int a, int b, int c, int d) {
if (b < a) {
if (c < a) {
if (d < a) {
std::cout << a;
} else { // a <= d
std::cout << d;
}
} else { // b < a <= c
if (c < d) {
std::cout << d;
} else {
std::cout << c;
}
}
} else { // a <= b
if (c < b) {
if (d < b) {
std::cout << b;
} else { // b <= d
std::cout << d;
}
} else { // a <= b <= c
if (c < d) {
std::cout << d;
} else {
std::cout << c;
}
}
}
}
But, as shown in other answer, there is simpler ways.
or with std:
void DisplayMax(int a, int b, int c, int d) {
std::cout << std::max({a, b, c, d});
}
I see a few issues:
Your logic seem over complicated for printing the largest of 4 variables.
The name of the isMax function doesn't reflect what it does.
I don't understand the need for a "invalid numbers ahead" if indeed printing the largest of four integers is intended.
I propose a simpler logic with fewer conditions but another variable on the heap.
#include <iostream>
int largestOf(int a, int b, int c, int d) {
int max = a;
if (b > max)
max = b;
if (c > max)
max = c;
if (d > max)
max = d;
return max;
}
void isMax(int a, int b, int c, int d) {
std::cout << largestOf(a, b, c, d) << std::endl;
}
It's not clear at all what you expect the a = !b, ... to accomplish, so I'm going to ignore that.
I am also going to ignore the existence of std::max since this is clearly an exercise.
Your logic tree makes sense, but you can find a more convenient solution if you bark up a different but similar tree.
Consider the case when a > b, i.e. you know for certain that b is not the maximum.
Instead of continuing with a, now look at only c and d.
If c > d, you know that the maximum is not d, so it must be either a or c.
Likewise, if d > c, the maximum is either a or d.
The same line of reasoning for the case when b > a leads to the following algorithm:
Determine max(a,b).
Determine max(c,d).
The maximum of all four numbers is the maximum of the previous two results.
In code:
void isMax(int a, int b, int c, int d) {
int ans0 = a > b ? a : b;
int ans1 = c > d ? c : d;
std::cout << (ans0 > ans1 ? ans0 : ans1) << std::endl;
}
On a side note, a function whose name begins with "is" usually returns a boolean, and you will find more use for a function that returns the maximum than you will of one that prints it.
You can always print that value later if you want to look at it.
Like this:
int max(int a, int b, int c, int d) {
int ans0 = a > b ? a : b;
int ans1 = c > d ? c : d;
return ans0 > ans1 ? ans0 : ans1;
}
This code is over complicated for something fairly simple. If you're new to programming, I suggest you try using arrays, in that way you can easily decide which number is max.
For example:
void isMax(int a, int b, int c, int d) {
int j[4] = { a,b,c,d };
int max = j[0];
for (int i = 1; i < 4; i++) {
if (j[i] > max){ max = j[i]; }
}
cout << max;
}
This is a better way to do it.
I have this recursive function that decompose a number in its prime factors, and show the result standard output for example
descompon(2, 10);
Output
2 = 2
3 = 3
4 = 2^2
5 = 5
6 = 2 * 3
7 = 7
8 = 2^3
9 = 3^2
10 = 2 * 5
The code
#include <iostream>
#include <sstream>
int comprobar_primo( int* num, int e )
{
if (*num%e == 0)
{
*num /= e;
return 1 + comprobar_primo(num, e);
}
return 0;
}
std::string factor_primo(int a, int b, std::stringstream& fact)
{
unsigned exp = comprobar_primo(&a, b);
if (exp >= 1)
{
fact << b;
if (exp > 1) fact << '^' << exp;
if (a != 1) fact << " * ";
}
if (a > 1) factor_primo(a, b + 1, fact);
return fact.str();
}
void descompon(int a, int b, int ver)
{
std::stringstream fact;
//std::string result = factor_primo(a, 2, fact);
if(ver)
std::cout << a << " = " << factor_primo(a, 2, fact) << std::endl;
if(a < b)
descompon( a + 1, b, ver);
}
int main(void)
{
descompon(2, 10000, 1);
return 0;
}
The problem is that when reaches the 5922 the program remains frozen, showing:
Process returned -1073741819 <0xC0000005>
why this happens and how I can avoid?
Both your factor_primo and descompon functions can potentially cause stack overflow. Its better to convert them into iterative version. Modified code is given below:
// no need to pass b as argument since we start from b=2 and increment b by 1
std::string factor_primo(int a, std::stringstream& fact)
{
for(int b=2; a>1; b++)
{
if(a%b==0)
{
unsigned exp=comprobar_primo(&a, b);
if(exp >= 1)
{
fact << b;
if(exp > 1) fact << '^' << exp;
if(a != 1) fact << " * ";
}
}
}
return fact.str();
}
void descompon(int a, int b, int ver)
{
if(ver)
{
for(int i=a; i<=b; i++) {
std::stringstream fact;
std::cout << i << " = " << factor_primo(i, fact) << std::endl;
}
}
}
int main(void)
{
descompon(2, 10000, 1);
getchar();
return 0;
}
I wanted to practice math in c++ and I tried making a program that answered this question from math class
0 < r < 1, find the number of rational r values for which the
numerator and the denominator add to make 1000 where r is in simplest
form
After an hour or two debugging, I finally got something that makes it through all the numbers. In class, the answer was 200. I got 216. Run for yourself
#include <math.h>
#include <iostream>
bool rprime_test(int a, int b) {
int tmp = 2;
std::cout << a << "/" << b;
tmp1:
for (tmp; (tmp < a) && (a % tmp != 0); tmp++) {
}
if ((b % tmp == 0 && a % tmp == 0) || b % a == 0) {
std::cout << " == irreduced\n";
return false;
} else if (!tmp < a) {
std::cout << " == reduced\n";
return true;
} else {
//std::cout << tmp << ","<< a << std::endl;
goto tmp1;
}
}
int main() {
int r = 0, a = 1;
int b = 1000 - a;
while (a < b) {
if (rprime_test(a, b)) {
r++;
}
std::cout << "total = " << r << std::endl;
a++;
b = 1000 - a;
//std::cout << "assigned " << a << "/" << b << std::endl;
}
std::cout << "final result = " << r << std::endl;
return 0;
}
please I don't know what I did wrong for this. Also, is there any better way to optimize this?
Your main issue is with your rprime_test function. Without digging too much into your existing function, try using the gcd. Two numbers a and b are an irreducible fraction when they are "coprime," which is when their "greatest common denominator" (gcd) is 1. The way you compute the gcd of two values is with the Euclidean Algorithm:
int gcd (int a, int b) {
return b % a == 0 ? a : gcd (b % a, a);
}
And your check becomes
if (gcd (a, b) == 1) {
a++;
/* etc */
}
Following works:
#include <iostream>
int gcd(unsigned int a, unsigned int b)
{
if (b < a) {
return gcd(b, a);
}
int r = a % b;
while (r != 0) {
a = b;
b = r;
r = a % b;
}
return b;
}
int main()
{
int count = 0;
for (int i = 1; i != 500; ++i) {
if (gcd(1000 - i, i) == 1) {
++count;
}
}
std::cout << count << std::endl;
}
Live example
I am trying to create a program that can take many numbers as I want in C++ language.
Then it find what operators can make the equation true and show all correct possible operation.
Example: If I put 3 5 15
Then it output 3x5 = 15
If I put 1 2 3 4 4
Then it outputs 1+2-3+4 =4
The following code is my written program:
The problem about it is that when I want to reduce the number of input or increase the number of input I need to add/reduce nested loops EVERYTIME. I want to know what is a more effective way of a more flexible nested loops or recursion method.
#include <iostream>
#include <cmath>
using namespace std;
char getOperator(int);
double operate(int, double, double);
int main() {
double a, b, c, d, e, result;
short noOfAnswers = 0;
cout << "Input first 5 numbers to make it equal to another 1 number.\n" <<
"I'll find what are the operators needed to make 2 sides of the equation equal.\n";
cin >> a >> b >> c >> d >> e >> result;
int noOfOperators = 5;
for (int i = 0; i <= noOfOperators; i++) {
double firstTwo = operate(i, a, b);
for (int j = 0; j <= noOfOperators; j++) {
double firstThree = operate(j, firstTwo, c);
for (int k = 0; k <= noOfOperators; k++) {
double firstFour = operate(k, firstThree, d);
for (int l = 0; l <= noOfOperators; l++) {
double firstFive = operate(l, firstFour, e);
if (firstFive == result) {
cout << ++noOfAnswers << ')' << a << getOperator(i) << b << getOperator(j) << c
<< getOperator(k) << d << getOperator(l) << e << '=' << result << endl;
}
}
}
}
}
if (noOfAnswers) cout << "I have found " << noOfAnswers << " solutions for this extremely hard problem for humanity \nin less than a second." << endl;
else cout << "I cannot find any solutions to this problem.\n"
<<"They're just a bunch of random numbers & That is UNSOLVABLE!" << endl;
cout << "Do not doubt my judgment. I am always right!" << endl << "(Please note that all calculations are done from the left side first.)" << endl;
return 0;
}
double operate(int iteration, double num1, double num2) {
switch (iteration) {
case 0: return num1+num2;
case 1: return num1-num2;
case 2: return num1*num2;
case 3: return num1/num2;
case 4: return pow(num1, num2);
case 5: return fmod(num1, num2);
}
return 0;
}
char getOperator(int pos) {
switch (pos) {
case 0: return '+';
case 1: return '-';
case 2: return 'x';
case 3: return '/';
case 4: return '^';
case 5: return '%';
}
return ' ';
}
You might want to use while() loops, cause you dont know when the loop terminates.
int main() {
double numbers[] = {3,5,15};//consider storing the number as an array
//the last element is the result
double result;
int arr_len = sizeof(numbers)/sizeof(double);
int i,j;
while(1)
{
j = 0;
while(j++ < 5)//over all operators
{i = 0;
result = numbers[0];//start with first element
while(i < arrlen - 2)//over all numbers, exclude the result
{
result = operate(j, result, numbers[++i]);
//something like this...this does not work correctly
//it might give you a hint in the right direction
if(result == numbers[arr_len - 1])//compare to last element
return 0;
}
}
}
return 0;
}
Following may help:
// increment v where each value is a digit with maximal value maxSize
// so {0,1,2}, 3 lead to {0,2,0}
// return false on overflow.
bool increment(std::vector<int>& v, int maxSize)
{
for (auto it = v.rbegin(); it != v.rend(); ++it) {
++*it;
if (*it != maxSize) {
return true;
}
*it = 0;
}
return false;
}
// display something like 1 + 2 * 3 = 9 // with the following meaning ((1 + 2) * 3) = 9
void display(const std::vector<double>& operands, const std::vector<int>& operators, double total)
{
const char operators_string[] = "+-*/^%";
std::cout << operands[0];
for (std::size_t i = 0; i != operators.size(); ++i) {
std::cout << " " << operators_string[operators[i]] << " " << operands[i + 1];
}
std::cout << " = " << total << std::endl;
}
// Compute something like {1 2 3 4}, {+ * /} as (((1 + 2) * 3) / 4)
double compute(const std::vector<double>& operands, const std::vector<int>& operators)
{
std::function<double(double, double)> fs[] = {
[](double a, double b) { return a + b; },
[](double a, double b) { return a - b; },
[](double a, double b) { return a * b; },
[](double a, double b) { return a / b; },
[](double a, double b) { return pow(a, b); },
[](double a, double b) { return fmod(a, b); },
};
double res = operands[0];
for (std::size_t i = 0; i != operators.size(); ++i) {
res = fs[operators[i]](res, operands[i + 1]);
}
return res;
}
void display_combinaison(const std::vector<double>& operands, double total)
{
std::vector<int> operators(operands.size() - 1);
do {
if (compute(operands, operators) == total) {
display(operands, operators, total);
}
} while (increment(operators, 6));
}
Live example