如何使用运算符重载来简化两个分数的加法?

时间:2019-04-20 01:38:24

标签: c++

我需要使用运算符重载来简化两个分数的相加。我想获得极简主义的结果​​。我使用两次欧几里得算法,第一次得到分母的倍数。第二次,我想简化分数。 像这两个部分一样

1 10
1 10

结果:

1 5

将两个数字相加并简化

主要代码段:

Fraction operator+(const Fraction &a1, const Fraction &a2) {

    int max, min, temp_1 , temp_2, n, m, sum, max_1, min_1, temp_3 ;
    if (a1.numerator < a2.numerator) {
        max = a2.numerator;
        min = a1.numerator;
    } else {
        max = a1.numerator;
        min = a2.numerator;
    }
    //euclidean algorithm 
    while (max % min != 0) {
        temp_1 = max % min;
        max = min;
        min = temp_1;
    }
    //Least common multiple
    temp_2 = max * min / temp_1;

    n = temp_2 / a1.numerator * a1.denominator;
    m = temp_2 / a2.numerator * a2.denominator;
    sum = n + m;
    if (sum > temp_2) {
        max_1 = sum;
        min_1 = temp_2;
    } else {
        max_1 = temp_2;
        min_1 = sum;
    }
    //euclidean algorithm 
    while (max_1 % min_1 != 0) {
        temp_3 = max_1 % min_1;
        max_1 = min_1;
        min_1 = temp_3;
    }
    sum = sum / temp_3;
    temp_2 = temp_2 / temp_3;
    return Fraction(sum, temp_2);
}

完整代码:

#include <iostream>

using namespace std;

class Fraction {
private:

    int numerator, denominator;
public:
    Fraction(int numerator1=0, int denominator1=0) : numerator(numerator1), denominator(denominator1) {}
    void show() const; //Output all data
    friend Fraction operator+(const Fraction &a1, const Fraction &a2);
};
void Fraction::show() const {
    cout << "x/y= " << numerator << " / " << denominator << endl;
}
Fraction operator+(const Fraction &a1, const Fraction &a2) {

    int max, min, temp_1 , temp_2, n, m, sum, max_1, min_1, temp_3 ;
    if (a1.numerator < a2.numerator) {
        max = a2.numerator;
        min = a1.numerator;
    } else {
        max = a1.numerator;
        min = a2.numerator;
    }
    //euclidean algorithm 
    while (max % min != 0) {
        temp_1 = max % min;
        max = min;
        min = temp_1;
    }
    //Least common multiple
    temp_2 = max * min / temp_1;

    n = temp_2 / a1.numerator * a1.denominator;
    m = temp_2 / a2.numerator * a2.denominator;
    sum = n + m;
    if (sum > temp_2) {
        max_1 = sum;
        min_1 = temp_2;
    } else {
        max_1 = temp_2;
        min_1 = sum;
    }
    //euclidean algorithm 
    while (max_1 % min_1 != 0) {
        temp_3 = max_1 % min_1;
        max_1 = min_1;
        min_1 = temp_3;
    }
    sum = sum / temp_3;
    temp_2 = temp_2 / temp_3;
    return Fraction(sum, temp_2);
}
int main() {
    Fraction a1(1 ,5);
    Fraction a2(3, 5);
    Fraction a;
    cout << "a1: ";
    a1.show();
    cout << "a2: ";
    a2.show();
    cout << "a: " ;
    a = a1 + a2;
    a.show();

}

3 个答案:

答案 0 :(得分:1)

目前尚不清楚您遇到什么问题,因此我以“没有得到结果”为前提,您没有得到预期的结果。

错误的一个来源是,temp_1在最小公倍数计算中使用时可能未初始化。 (如果maxmin的倍数,并且在您的特定测试中,因为min是1,则会发生此情况。)如果警告级别足够高,则编译器可以为此发出警告

另一个问题是您的代码无法处理零分数。似乎Fraction的一个参数构造函数(分母默认为0)是错误的,分母应为1。

答案 1 :(得分:1)

我无法理解您的代码中使用欧几里得算法。还可以使用诸如hcf,lcm之类的变量代替temp1或temp2来阐明您的意图。这是使用欧几里得定理计算分母的hcf和lcm的代码段。

Fraction operator+(const Fraction &a1, const Fraction &a2)
{
    int max, min, hcf, lcm, num;

    if (a1.denominator < a2.denominator) {
        max = a2.denominator;
        min = a1.denominator;
    }
    else {
        max = a1.denominator;
        min = a2.denominator;
    }

        //euclidean algorithm 
        if (max % min == 0)
        {
            hcf = min;
        }
        else
        {
            while (max % min != 0) {
                hcf = max % min;
                max = min;
                min = hcf;
            }
        }

        lcm = (a1.denominator * a2.denominator) / hcf;

        num = a1.numerator * lcm / a1.denominator + a2.numerator * lcm / a2.denominator;

        return Fraction(num, lcm);
}

答案 2 :(得分:1)

加法太复杂了。
(用一个非常简单的算术运算就几乎不可能分辨出什么地方是一个有力的指标。)

首先将Euclides提取为函数:

int gcd(int a, int b)
{
    if (a < b)
        return gcd(b, a);
    while (b != 0) {
        int t = b;
        b = a % b;
        a = t;
    }
    return a;
}

(或者,如果您使用的是C ++ 17-现代的,则使用std::gcd。)

然后重写构造函数以简化操作(您不想强迫类的用户担心):

Fraction(int numerator1=0, int denominator1=1) 
{
    int divisor = gcd(numerator1, denominator1);
    numerator = numerator1 / divisor;
    denominator = denominator1 / divisor;   
}

您还应该将默认分母设置为1,因为未定义除以零。
默认情况下,无效的分数是个坏主意。

有了这个,加法几乎变得微不足道了:

Fraction operator+(const Fraction &a1, const Fraction &a2) {
    int numerator = a1.numerator * a2.denominator + a2.numerator * a1.denominator;
    int denominator = a1.denominator * a2.denominator;
    return Fraction(numerator, denominator);
}