C++ 课程作业 群体类和群体数据的组织(模板数组类(支持分数和浮点数的求和计算))

首先是题目
【问题描述】
封装一个模板数组类Array,支持以下操作:

  1. 构造函数Array(int n),将数组初始化为n个存储空间,建议使用vector;
  2. 函数input(int n),使用插入运算符<<读取数据,最多读取n个元素,但不能超过数组存储空间的上限;
  3. 重载下标运算符,返回数组的元素。

封装一个分数类Fract,用来处理分数功能和运算,能支持你的Array类使用。

  1. 构造:传入两个参数n和m,表示n/m;分数在构造时立即转化成最简分数。
    提示:分数化简有专门的算法,可自行调研
  2. show()函数:分数输出为“a/b”或“-a/b”的形式,a、b都是无符号整数。若a为0或b为1,只输出符号和分子,不输出“/”和分母。
  3. 在分数类上重载+=运算符,进行分数的加法运算。

【输入形式】
输入为两部分,分别是一组实数测试样例和一组分数测试样例。
这两组测试样例都以正整数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
这次作业还学到了下标的重载。
使用模板类的实例时需要注意一些运算符的重载。
最大公约数的函数很常用,很简单,记住就好。
代码如有不妥,还请指正

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值