如何使用运算符重载来简化两个分数的添加?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用运算符重载来简化两个分数的添加?相关的知识,希望对你有一定的参考价值。
我需要使用运算符重载来简化两个分数的添加。我希望得到极简主义的结果。我使用了两次欧几里德算法,第一次,我得到了分母的倍数。第二次,我想简化分数。像这两个分数
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();
}
答案
这个增加太复杂了。 (几乎不可能分辨出什么应该是一个非常简单的算术运算可能是错误的,这是一个强有力的指标。)
首先将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;
}
(或者使用std::gcd
,如果你是C ++ 17-modern。)
然后重写构造函数以进行简化(您不希望强制您的类的用户担心这一点):
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
在最小公倍数计算中使用时可以未初始化。 (如果max
是min
的倍数,并且在您的特定测试中,因为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);
}
以上是关于如何使用运算符重载来简化两个分数的添加?的主要内容,如果未能解决你的问题,请参考以下文章