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

How to use operator overloading to simplify the addition of two fractions?

本文关键字:两个 添加 运算符 何使用 重载      更新时间:2023-10-16

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

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();
}

这种添加太复杂了。
(几乎不可能说出应该非常简单的算术运算可能出了什么问题,这是一个强有力的指标。

从将欧几里得提取到函数中开始:

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;
}

(或者使用std::gcd,如果你是C++17-现代。

然后重写构造函数进行简化(您不想强迫类的用户担心这一点(:

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);
}

目前还不清楚您遇到了什么问题,因此我将通过"没有得到结果"来假设您没有得到预期的结果。

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

另一个问题是您的代码不处理零分数。 似乎 Fraction 的一个参数构造函数(其中分母默认为 0(是错误的,分母应该是 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);
}