首先是题目
【问题描述】
封装一个模板数组类Array,支持以下操作:
- 构造函数Array(int n),将数组初始化为n个存储空间,建议使用vector;
- 函数input(int n),使用插入运算符<<读取数据,最多读取n个元素,但不能超过数组存储空间的上限;
- 重载下标运算符,返回数组的元素。
封装一个分数类Fract,用来处理分数功能和运算,能支持你的Array类使用。
- 构造:传入两个参数n和m,表示n/m;分数在构造时立即转化成最简分数。
提示:分数化简有专门的算法,可自行调研 - show()函数:分数输出为“a/b”或“-a/b”的形式,a、b都是无符号整数。若a为0或b为1,只输出符号和分子,不输出“/”和分母。
- 在分数类上重载+=运算符,进行分数的加法运算。
【输入形式】
输入为两部分,分别是一组实数测试样例和一组分数测试样例。
这两组测试样例都以正整数n,且n小于1000,n表示需要输入n个实数(或分数)。
测试样例的第二行开始为n个实数(或分数)。其中每个分数输入为两个整数n、m,表示分数n/m。
【输出形式】
第一部分输出一个实数,是第一组测试样例之和;第二部分输出一个分数,是第二组测试样例之和。
分数输出时为最简形式,负号只会出现在最前面,若分母为1或分子为0,则只输出一个整数,即分子部分,而没有“/”和分母部分。
然后是代码
#include <iostream>
#include <vector>
using namespace std;
int gcd(int a, int b) {
return b == 0 ? a: gcd(b, a % b);
}//求最大公约数的函数
template <typename T>
//定义一个模板T
//这样clss类所有函数的实现前都需要加上template <typename T>
class Array
{
public:
Array(int n) { a.resize(n); }
// 构造函数,将数组初始化为n个存储空间
void input(int n);
T& operator [](int i) { return a[i]; }
//重载下标运算符,返回数组的元素。
private:
vector<T> a;//使用vector方便初始化数组
};
template <typename T>
void Array<T>::input(int n)
//使用<<读取数据,读取n个元素
{
for (int i = 0; i < n; i++)
cin >> a[i];
}
class Fract
{
public:
Fract(int n=0, int m=0);
//构造函数,n和m表示n/m;分数在构造时立即转化成最简分数
void show();
void operator +=(Fract i);//重载+=运算符,进行分数的加法运算
friend istream& operator >> (istream& ci, Fract& i);
//重载>>,因为根据提供的main()函数, fr.input(n);会需要Fract类的读取
private:
int a, b;
};
istream& operator >> (istream& ci, Fract& i)
{
ci >> i.a >> i.b;
return ci;
} //重载>>,因为是友元函数所以可以直接调用私有成员
Fract::Fract(int n, int m)
{
int x=gcd(n, m);
a = n/x;
b =n==0? m: m/x;
}//分数在构造时立即转化成最简分数,gcd(n,m)返回n,m的最大公约数
void Fract::show()
{
if (a == 0)
cout << "0" << endl;
else if (b == 1)
cout << a << endl;
else
cout << a << "/" << b;
}//分数输出为“a/b”或“-a/b”的形式。
//若a为0或b为1,只输出符号和分子,不输出“/”和分母。
void Fract::operator+=(Fract i)
{
a = a * i.b + i.a * b;
b = b * i.b;
int x = gcd(a, b);
a = a/x ;
b = a == 0 ? b : b/x;
}//重载+=运算符,进行分数的加法运算
int main()
{
unsigned int n;
cin >> n;
Array<double> db(n);
db.input(n);
double dbsum(0.0);
for (unsigned int i = 0; i < n; i++)
dbsum += db[i];
cout << dbsum << endl;
cin >> n;
Array<Fract> fr(n);
fr.input(n);
Fract frsum(0, 1);
for (unsigned int i = 0; i < n; i++)
frsum += fr[i];
frsum.show();
}
总结:使用模板类后,所有模板类函数的实现都需要加上template
这次作业还学到了下标的重载。
使用模板类的实例时需要注意一些运算符的重载。
最大公约数的函数很常用,很简单,记住就好。
代码如有不妥,还请指正