使用运算符重载添加分数
Add fractions using operator overloading
在一次采访中,我被要求创建两个 classes。第一个抽象class叫做Number,它支持一个操作“+”。另一个部分实现了 "Number" 抽象 class.
进一步:对于添加后的分数,需要以其原始形式显示。即2/4必须显示为“2/4”,而不是“1/2”或“0.5”。
没有向我提供其他详细信息。
以下是我试过的(不完整)。
我的main.cpp
#include <iostream>
#include "Fraction.h"
using namespace std;
int main()
{
Fraction sumFraction;
Fraction n11(1,2);
Fraction n21(1,2);
cout << n11.getValuenum() << "/";
cout << n11.getValueden() << endl;
cout << n21.getValuenum() << "/";
cout << n21.getValueden() << endl;
sumFraction = n11 + n21;
cout << sumFraction.getValuenum() << endl;
cout << sumFraction.getValueden() << endl;
return 0;
}
我的Numbers.h // 摘要CLASS
#pragma once
template<class T>
class Number
{
virtual T& operator= (const T &) = 0; // first parameter is implicitly passed
virtual const T operator+ (const T &) = 0;
virtual void display() = 0;
};
我的Fraction.cpp
#include "Fraction.h"
int Fraction::getValuenum()
{
return this->a1;
}
int Fraction::getValueden()
{
return this->a2;
}
Fraction::Fraction()
{
a1 = 0;
a2 = 0;
}
Fraction::Fraction(int num, int den)
{
a1 = num;
a2 = den;
}
void Fraction::display()
{
// will display the number in its original form
}
Fraction& Fraction::operator=(const Fraction &num)
{
a1 = num.a1;
a2 = num.a2;
return *this;
}
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
Fraction n1;
n1.a1 = this->a1*numberTwo.a2 + this->a2*numberTwo.a1;
n1.a2 = this->a2*numberTwo.a2;
return n1;
}
我的Fraction.h
#pragma once
#include "Number.h"
class Fraction : public Number<Fraction>
{
private:
int a1;
int a2;
public:
void display();
Fraction();
Fraction(int num, int den);
int getValuenum();
int getValueden();
Fraction& operator= (const Fraction &); // first parameter is implicitly passed
const Fraction operator+ (const Fraction &); // first parameter is implicitly passed
};
以下是我的问题:
我真的需要为每个分数从我的 Main 函数中单独传递分子和分母吗?目前,我将它作为单独传递以跟踪分子和分母,这在以分数形式添加和返回结果时可能会有所帮助。
使用我的运算符 + 逻辑,如果我添加 1/4+1/4,我得到 8/16,预期的是我猜 2/4,如果我们正常添加,我们会得到。那么如何使用分子和分母相加并以这种方式保留分数,这样如果输出是 2/4 那么 2/4 而不是 1/2 或 0.5。
请帮帮我。
一些备注:
- 你不应该让分母为 0,因为它给出了一个不存在的数(无穷大或未确定)
- 你绝对应该不出于同样的原因将分母初始化为0(1似乎是更合理的值)
分数的正确(数学)加法是 (*):
a/b + c/d = (ad +bc)/bd
我建议您编写 ostream& operator << (ostream&, const Fraction&)
重载来代替(或补充)显示方法。那会让你只写你的 main
std::cout << n11 << " + " << n21 << " = " << sumFraction << std::endl;
我不是很理解你的第一个问题,但我会添加一个从 int 的转换:
Fraction(int n): a1(n), a2(1) {};
允许直接写Fraction(1, 2) + 1
或Fraction(1) + Fraction(1/2)
(加法的第一个元素必须是Fraction)
(*) 这是简单通用的方法。您还可以使用最小公倍数来获得更清晰的结果:
den = lcm(b,d)
a/b + c/d = (a * den/b) + c * den/d) / den
这样你会得到 1/4 + 2/4 = 3/4 而不是 12/16
但是computing the LCM远远超出了这个答案...
在一次采访中,我被要求创建两个 classes。第一个抽象class叫做Number,它支持一个操作“+”。另一个部分实现了 "Number" 抽象 class.
进一步:对于添加后的分数,需要以其原始形式显示。即2/4必须显示为“2/4”,而不是“1/2”或“0.5”。
没有向我提供其他详细信息。
以下是我试过的(不完整)。
我的main.cpp
#include <iostream>
#include "Fraction.h"
using namespace std;
int main()
{
Fraction sumFraction;
Fraction n11(1,2);
Fraction n21(1,2);
cout << n11.getValuenum() << "/";
cout << n11.getValueden() << endl;
cout << n21.getValuenum() << "/";
cout << n21.getValueden() << endl;
sumFraction = n11 + n21;
cout << sumFraction.getValuenum() << endl;
cout << sumFraction.getValueden() << endl;
return 0;
}
我的Numbers.h // 摘要CLASS
#pragma once
template<class T>
class Number
{
virtual T& operator= (const T &) = 0; // first parameter is implicitly passed
virtual const T operator+ (const T &) = 0;
virtual void display() = 0;
};
我的Fraction.cpp
#include "Fraction.h"
int Fraction::getValuenum()
{
return this->a1;
}
int Fraction::getValueden()
{
return this->a2;
}
Fraction::Fraction()
{
a1 = 0;
a2 = 0;
}
Fraction::Fraction(int num, int den)
{
a1 = num;
a2 = den;
}
void Fraction::display()
{
// will display the number in its original form
}
Fraction& Fraction::operator=(const Fraction &num)
{
a1 = num.a1;
a2 = num.a2;
return *this;
}
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
Fraction n1;
n1.a1 = this->a1*numberTwo.a2 + this->a2*numberTwo.a1;
n1.a2 = this->a2*numberTwo.a2;
return n1;
}
我的Fraction.h
#pragma once
#include "Number.h"
class Fraction : public Number<Fraction>
{
private:
int a1;
int a2;
public:
void display();
Fraction();
Fraction(int num, int den);
int getValuenum();
int getValueden();
Fraction& operator= (const Fraction &); // first parameter is implicitly passed
const Fraction operator+ (const Fraction &); // first parameter is implicitly passed
};
以下是我的问题:
我真的需要为每个分数从我的 Main 函数中单独传递分子和分母吗?目前,我将它作为单独传递以跟踪分子和分母,这在以分数形式添加和返回结果时可能会有所帮助。
使用我的运算符 + 逻辑,如果我添加 1/4+1/4,我得到 8/16,预期的是我猜 2/4,如果我们正常添加,我们会得到。那么如何使用分子和分母相加并以这种方式保留分数,这样如果输出是 2/4 那么 2/4 而不是 1/2 或 0.5。
请帮帮我。
一些备注:
- 你不应该让分母为 0,因为它给出了一个不存在的数(无穷大或未确定)
- 你绝对应该不出于同样的原因将分母初始化为0(1似乎是更合理的值)
分数的正确(数学)加法是 (*):
a/b + c/d = (ad +bc)/bd
我建议您编写 ostream& operator << (ostream&, const Fraction&)
重载来代替(或补充)显示方法。那会让你只写你的 main
std::cout << n11 << " + " << n21 << " = " << sumFraction << std::endl;
我不是很理解你的第一个问题,但我会添加一个从 int 的转换:
Fraction(int n): a1(n), a2(1) {};
允许直接写Fraction(1, 2) + 1
或Fraction(1) + Fraction(1/2)
(加法的第一个元素必须是Fraction)
(*) 这是简单通用的方法。您还可以使用最小公倍数来获得更清晰的结果:
den = lcm(b,d)
a/b + c/d = (a * den/b) + c * den/d) / den
这样你会得到 1/4 + 2/4 = 3/4 而不是 12/16
但是computing the LCM远远超出了这个答案...