C++ Fraction class does not work on negatives - c++

I am trying to create a fraction class that can do operations on fractions just like the way we did it by hand in elementary school. It works fine with positive numbers but I have tried implementing it with negative numbers and I get breakpoint error. It would be great if someone can tell me what is wrong with it.
#include <iostream>
#include <cmath>
using namespace std;
class fraction
{
private:
long int n;
long int d;
long int gcd();
public:
fraction(long int, long int);
long int num(); //returns num
long int denom(); //returns denom
void print(); //print fraction
void reduce(); //reduce fraction to lowest terms
friend double convert(fraction); //convert function to double
friend fraction operator+ (fraction, fraction);//add two fractions, answer in reduced form
friend fraction operator- (fraction, fraction);//subtract two fractions, reduced
};
long int fraction::gcd()
{
long int divisor = 0;
for (long int i = 1; (i <= n && i <= d) ; i++)
{
if ((n % i == 0) && (d % i == 0))
{
divisor=i;
}
}
return divisor;
}
fraction::fraction(long int x, long int y) //constructor
{
n=x;
d=y;
if ((x <= 0) && (y <= 0))
{
n = -x;
d = -y;
}
}
void fraction::reduce() //change value of n and d
{
long int num = n/gcd();
long int denom = d/gcd();
n = num;
d = denom;
}
long int fraction::num()
{
return n;
}
long int fraction::denom()
{
return d;
}
void fraction::print()
{
cout << n << "/" << d;
}
fraction operator- (fraction x, fraction y)
{
x.reduce();
y.reduce();
fraction temp;
temp.n = (x.n)*(y.d) - y.n*(x.d);
temp.d = (x.d)*(y.d);
temp.reduce();
return temp;
}
int main()
{
fraction f(-5,100), g(-1,-2);
(f-g).print; //returns error!
return 0;
}

The error is caused by the fact that print() is a non-const member function.
When you use:
(f-g).print();
The function is called an a temporary object, which is good for calling const member functions, not non-const member functions.
You can resolve this problem by:
Changing print() to a const member function.
By assigning f-g to an object and calling print on that object.
fraction res = f-g;
res.print();
I would recommend using the first method.
Update
You have a problem in gcd when either n or d is negative. Change it to:
long int fraction::gcd()
{
long int divisor = 1;
// Deal with only positive numbers when computing the gcd.
long int tempN = n < 0 ? -n : n;
long int tempD = d < 0 ? -d : d;
for (long int i = 1; (i <= tempN && i <= tempD) ; i++)
{
if ((tempN % i == 0) && (tempD % i == 0))
{
divisor=i;
}
}
return divisor;
}

Related

Friend Function C++ how to design the function that takes 2 class objects as the argument

I find difficulties in this part because it takes the class objects as the parameter of the function:
friend Num_Fact GCD(Num_Fact , Num_Fact);
friend Num_Fact LCM(Num_Fact , Num_Fact);
How to implement the GCD function with arguments of 2 class objects, and return the value back in as Num_Fact as following in cpp:
cin >> value;
Num_Fact A(value);
cout << "Key in number B: ";
cin >> value;
Num_Fact B(value);
cout << " A = "<< A.output() <<" = "<<A.getnum()<<endl;
cout << " B = " <<B.output() << " = " << B.getnum() << endl;
Num_Fact C = GCD(A, B);
Original Code:
#ifndef NUM_FACTOR
#define NUM_FACTOR
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
using namespace std;
#define Z 20
class Num_Fact {
friend Num_Fact GCD(Num_Fact , Num_Fact);
friend Num_Fact LCM(Num_Fact , Num_Fact);
public:
Num_Fact(int num) {
Num = num;
}
~Num_Fact() {};
long long int findgcd(long long int a, int b) {
if (b == 0) return a;
return findgcd(b, a % b);
}
long long int LCM2(long long int a[], int n) {
long long int res = 1, i;
for (i = 0; i < n; i++) {
res = res * a[i] / findgcd(res, a[i]);
}
fact2num(res);
return res;
}
long long int GCD2(long long int arr[], int n)
{
long long int result = arr[0];
for (int i = 1; i < n; i++)
{
result = findgcd(arr[i], result);
if (result == 1)
{
fact2num(result);
return 1;
}
}
fact2num(result);
return result;
}
long long int GCD(int a, int b) {
int temp;
while (b != 0) {
temp = b;
b = a % b;
a = temp;
}
return a;
}
long long int LCM(int a, int b) {
int lcm = (a * b) / GCD(a, b);
return lcm;
}
string Factorize() {
ostringstream output;
int fac = 2;
if (Num == 1) {
output << Num;
}
while (Num > 1)
{
if (Num % fac == 0)
{
output << fac << "^"; //print the base first
Num /= fac;
int pow = 1;
while (Num % fac == 0) //get the power of current base
{
Num /= fac;
pow++;
}
output << pow; //print out the power, now we have fac^pow printed
//if not the last factor, print a multiplication symbol
if (Num != 1)
output << " * ";
}
else
{
fac++;
}
}
return output.str();
}
string output() {
ostringstream output;
output << Factorize();
return output.str();
}
int getnum() {
return Num;
}
private:
int Num;
array<array<int, Z>, 2>fact;
};
#endif
Latest code for Header:
#ifndef NUM_FACTOR
#define NUM_FACTOR
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
using namespace std;
#define Z 20
int findgcd(long long int a, int b) {
if (b == 0) return a;
return findgcd(b, a % b);
}
int LCM2(long long int a[], int n) {
int res = 1, i;
for (i = 0; i < n; i++) {
res = res * a[i] / findgcd(res, a[i]);
}
return res;
}
int GCD2(long long int arr[], int n)
{
int result = arr[0];
for (int i = 1; i < n; i++)
{
result = findgcd(arr[i], result);
if (result == 1)
{
return 1;
}
}
return result;
}
int GCD1(int a, int b) {
int temp;
while (b != 0) {
temp = b;
b = a % b;
a = temp;
}
return a;
}
int LCM(int a, int b) {
int lcm = (a * b) / GCD1(a, b);
return lcm;
}
class Num_Fact {
public:
Num_Fact(int num) {
Num = num;
}
~Num_Fact() {};
string Factorize() {
ostringstream output;
int fac = 2;
if (Num == 1) {
output << Num;
}
while (Num > 1)
{
if (Num % fac == 0)
{
output << fac << "^"; //print the base first
Num /= fac;
int pow = 1;
while (Num % fac == 0) //get the power of current base
{
Num /= fac;
pow++;
}
output << pow; //print out the power, now we have fac^pow printed
//if not the last factor, print a multiplication symbol
if (Num != 1)
output << " * ";
}
else
{
fac++;
}
}
return output.str();
}
string output() {
ostringstream output;
output << Factorize();
return output.str();
}
int getnum() {
return Num;
}
private:
int Num;
array<array<int, Z>, 2>fact;
};
Num_Fact GCD(Num_Fact A, Num_Fact B) {
return GCD(A.getnum(), B.getnum());
}
Num_Fact LCM(Num_Fact A, Num_Fact B) {
return LCM(A.getnum(), B.getnum());
}
#endif
Latest Code for CPP
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
#include"Num_Factor.h"
using namespace std;
const int S = 20;
void bonus();
int main() {
int value;
cout << "Key in number A: ";
cin >> value;
Num_Fact A(value);
cout << "Key in number B: ";
cin >> value;
Num_Fact B(value);
cout << " A = "<< A.output() <<" = "<<A.getnum()<<endl;
cout << " B = " <<B.output() << " = " << B.getnum() << endl;
Num_Fact C=GCD(A, B);
return 0;
}
It gives error when compiling such as "Unhandled exception at 0x00007FF72E1A53DF in lab09.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000C850A03EB8)." And also its pointing at:
Num_Fact GCD(Num_Fact A, Num_Fact B) {
return GCD(A.getnum(), B.getnum());
}
Num_Fact LCM(Num_Fact A, Num_Fact B) {
return LCM(A.getnum(), B.getnum());
}
The task is to call the Num_Fact C= GCD(A,B), the program is about to find gcd and lcm using classes and by using constructor such as "Num_Fact"
There's a lot of confusion in your class design. but I'm only going to address some of it here. First question, ask yourself why are the int versions of GCD and LCM members of the Num_Fact class? These functions work on integers only, so there is absolutely no reason to put them in the Num_Fact class. So move them out of the class, it will simplify the answer to your actual question. Second question, why are these functions returning long long int? They have integer arguments and they can never return a value that is bigger than an int. So change them to return int, again this will simplify the answer to your actual question.
With those changes done we can talk about your actual question. As we've seen you already have functions that calculate GCD and LCM on integers, so just use those functions when you want to calculate GCD or LCM on Num_Fact. Like this
Num_Fact GCD(Num_Fact a, Num_Fact b) {
return GCD(a.getnum(), b.getnum());
}
Num_Fact LCM(Num_Fact a, Num_Fact b) {
return LCM(a.getnum(), b.getnum());
}
That's it, really simple. In fact these functions doesn't even need to be friends, since they are only using the public methods of Num_Fact.

How to write combinations recursively in C++

I wrote a program for finding combination(n Choose r = nCr) using for loop/iterations, wanted to know how to do the same using recursion.
Code is as follows:
#include<iostream>
using namespace std;
int main(){
int n,r;
float num = 1,denum = 1,comb = 1;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
for (int i = 1; i <= r; i++)
{
num *= (n-r+i);
}
for (int i = 1; i <= r; i++)
{
denum *= (i);
}
comb = num/denum;
cout<<"The number of combinations is "<<comb<<"\n";
}
The following code that I've written helps in finding nCr through recursion:
#include<iostream>
using namespace std;
float comb(int n,int r){
if(r!=0)
{
return (n-r+1)*comb(n,r-1)/r;
}
else
{
return 1;
}
}
int main(){
int n,r;
float com;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
if(n-r>=r)
{
com = comb(n,r);
}
else
{
com = comb(n,n-r);
}
cout<<"The number of combinations is "<<com<<"\n";
}
Had done this program recently, upon calling the com function in main(), the function is calling itself(i.e recurses) until r value becomes 0 after which it goes to the base statement i.e return 1 if r equals 0
If you just need a code, here it is
int findNumerator(int num, int i, int r) {
return num * (i != r ? findNumerator(num, i+1, r) : 1);
}
int findDenominator(int denum, int i, int r) {
return denum * (i != r ? findDenominator(denum, i+1, r) : 1);
}
int main(){
int n,r;
float num = 1,denum = 1,comb = 1;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
comb = findNumerator(num, 1, r) / findDenominator(denum, 1, r);
cout<<"The number of combinations is "<<comb<<"\n";
}

Sum and sum of squares of digits -coprime

For the paragraph L, R
its sum of digits and the sum of its squares (in the decimal) is co-
prime.
Count how many numbers in the paragraph L, R meet the above conditions
I was stuck on the sub21
exceeds time limit when R = 10^8 and Max R = 10^18:
#include<bits/stdc++.h>
using namespace std;
class tinhtong
{
public:
long long getSum(long long n)
{
long long int sum = 0;
while (n != 0)
{
sum = sum + (n % 10);
n = n/10;
}
return sum;
}
};
class binhphuong
{
public:
long long getpow(long long n)
{
long long poww = 0;
while (n != 0)
{
poww = poww + (n % 10)*(n % 10);
n = n/10;
}
return poww;
}
};
int main()
{
tinhtong g;
binhphuong h;
long long TONG=0,k,l,ucln;
long long int m,n;
cin>>n>>m;
for(n;n<=m;n++)
{
ucln=0;
k=g.getSum(n);
l=h.getpow(n);
while(k!=0 && l!=0)
{
if(k>l)
k-=l;
else
l-=k;
}
if(k==0)
ucln=l;
else
ucln=k;
if (ucln==1)
TONG++;
}
cout<<TONG;
return 0;
}
As mentioned in comments, you can calculate the sum and the sum of squares in one loop, avoiding multiple calls of same % operation.
Moreover, to calculate that two numbers are coprime, it is better to use the version of Euclide's algorithm that uses modulo instead of substractions. The code is below.
In this code, I use the fact that the sum of squares is greater or equal the sum.
I also use the fact that if the sum is a multiple of 2, it is also the case for the sum of squares.
If this code is not fast enough, you can try the suggestion in a comment to first convert the number to a string.
Another possibility would be the check if both numbers are multiple of 3 or 5, before calculating the GCD, as GCD calculation can be longer.
#include <iostream>
#include <tuple>
std::pair<long long, long long> getSum_pow(long long n) {
long long int sum = 0;
long long int sumP = 0;
while (n != 0) {
long long r = n%10;
sum += r;
sumP += r*r;
n = n/10;
}
return {sumP, sum};
};
int main() {
long long TONG = 0, a, b;
long long int m, n;
std::cin >> n >> m;
for(; n <= m; n++) {
std::tie (a, b) = getSum_pow(n);
if (b%2 == 0) continue;
while (b != 0) {
a = a%b;
std::swap (a, b);
}
if (a == 1) {
TONG++;
}
}
std::cout << TONG;
return 0;
}

C++ fraction operator overloading but main class not working

I am new in C++ and I have a problem with operator overloading. I just implemented the functions in the header file. I have completed the class as well but I cant get my main class to work. it doesn't send any output.
Please help my code is:
The header file:
class Fraction{
{
private:
int numerator;
int denominator;
public:
Fraction (int a=1, int b=1);
//declare Mutators
void setNumerator(int);
void setDenominator(int);
//declare Accessors
int getNumerator();
int getDenominator();
Fraction operator+(const Fraction &fra)const;
Fraction operator-(const Fraction &fra)const;
Fraction operator*(const Fraction &fra)const;
Fraction operator/(const Fraction &fra)const;
};
#endif /* FRACTION_H */
The Fraction.cpp
Fraction:: Fraction (int a,int b)
{
while (a<b && b<0)
{
if(b<0)
{
std:: cout<<"please enter a number grater then 0 in
denominator";
}
else
{
std:: cout<< "Please enter numerator greater then denominator";
}
}
numerator= a;
denominator= b;
}
void Fraction::setNumerator(int a)
{
numerator =a;
}
void Fraction::setDenominator(int a)
{
denominator =a;
}
// Operations
Fraction Fraction::operator-(const Fraction &f1)const
{
Fraction temp;
temp.numerator= (numerator*f1.denominator)-f1.numerator*denominator;
temp.denominator = denominator*f1.denominator;
for(int i = temp.numerator * temp.denominator ; i > 1; i--) //
{
if((temp.numerator % i == 0) && (temp. % i == 0))
{
{
temp.denominator /= i;
temp.numerator /= i;
}
}
}
return temp;
}
Fraction Fraction::operator+(const Fraction &f1)const
{
int a= (numerator*f1.denominator)+f1.numerator*denominator;
int b = denominator*f1.denominator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
Fraction Fraction::operator*(const Fraction &f1)const
{
int a= numerator *f1.numerator;
int b= denominator*f1.denominator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
Fraction Fraction::operator /(const Fraction& f1) const
{
int a= numerator *f1.denominator;
int b= denominator*f1.numerator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
std::ostream& operator<< (std::ostream &out, Fraction const& data) {
out << data.getDenominator() << ':';
out << data.getNumerator() << ':';
return out;
}
My main class so far is :
#include <iostream>
#include "fraction.h"
int main() {
Fraction f1(1,2);
std:: cout<<f1.getDenominator();
return 0;
}
I tryed to see if i can write my main but i had no luck on getting it.

How to select all possible combination of elements from a set using recursion

This is a question from hackerrank; I am trying to understand how recursion works.
The task at hand is:
Find the number of ways that a given integer, X, can be expressed
as the sum of the Nth power of unique, natural numbers.
So for example, if X = 100 and N = 2
100 = 10² = 6² + 8² = 1² + 3² + 4² + 5² + 7²
so 100 can be expressed as the square of unique natural numbers in 3
different ways, so our output is 3.
Here is my code,:
#include <cmath>
#include <iostream>
using namespace std;
int numOfSums(int x, int& n, const int k) {
int count = 0, j;
for (int i = (k + 1); (j = (int) pow(i, n)) <= x; i++) {
j = x - j;
if (j == 0)
count++;
else
count += numOfSums(j, n, i);
}
return count;
}
int main() {
int x, n;
cin >> x >> n;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
But when I input x = 100 and n = 2, it's outputting 2, not 3. What's wrong with the code?
Link to the question: https://www.hackerrank.com/challenges/the-power-sum
Your example code returns 3 when I run it using this main():
#include <iostream>
int main() {
int x = 100, n = 2;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
The problem is likely that you're using double std::pow(double, int), but you're not rounding the result to nearest integer ((int) casts round down). You should add ½ before truncating:
j = static_cast<int>(pow(i, n) + 0.5)
I've used the more-C++ style of cast, which I find clearer.
It would be more efficient to implement your own equivalent of std::pow() that operates on integers. That can be recursive, too, if you want:
unsigned long pow(unsigned long x, unsigned long n)
{
return n ? x * pow(x, n-1) : 1;
}
An iterative version is more efficient (or a tail-recursive version and suitable optimizing compiler).
Reduced version, with my changes:
template<typename T>
T powi(T x, T n)
{
T r{1};
for (; n; n /= 2) {
r *= n%2 ? x : 1;
x *= x;
}
return r;
}
template<typename T>
T numOfSums(T x, T n, T i = {})
{
T count{}, j;
for (++i; (j = powi(i, n)) <= x; ++i)
count += j == x ? 1 : numOfSums(x-j, n, i);
return count;
}
#include <iostream>
int main()
{
unsigned long int x = 100, n = 2;
std::cout << numOfSums(x, n) << std::endl;
return 0;
}