题目要求
三个类如下设计:类cTime有三个数据成员,hh,mm,ss,分别代表时,分和秒,并有若干构造函数和一个重载-(减号)的成员函数。类point有两个数据成员,x,y分别坐标,并有若干构造函数和一个重载-(减号)的成员函数。类date有三个数据成员,year,month,day分别代表年月日,并有若干构造函数和一个重载-(减号)的成员函数。
要求设计一个函数模板template <\class T>\ double dist(T a, T b) 对int,float,cTime,point和date或者其他类型的数据,返回间距。
其中,hh = 3600 * ss, mm = 60 * ss, year = 365 * day, month = 30 * day,对于cTime和date类型,数据在转换成ss或者day后进行运算。
输入格式:
每一行为一个操作,每行的第一个数字为元素类型,1为整型元素,2为浮点型元素,3为point类型,4,为time类型,5为date类型,若为整型元素,接着输入两个整型数据,
若为浮点型元素,接着输入两个浮点型数据,若为point型元素,输入两个point型数据(x1 y1 x2 y2),若为time型元素, 输入两个cTime型数据(hh1 mm1 ss1 hh2 mm2 ss2),若为date型数据,输入两个date型数据(year1 month1 day1 year2 month2 day2)。输入0时标志输入结束。
输出格式:
对每个输入,每行输出一个间距值。
样例输入:
1 2 5
4 18 21 22 18 20 31
3 2 4 5 9
5 2013 5 14 2013 5 15
2 2.2 9.9
0
样例输出:
3
51
5.83095
1
7.7
解题思路
定义 4 个类:Point、Time、Date 和一个未命名类(类别编号为 1 或 2 时使用),分别表示点、时间和日期。
在主函数中,首先读入一个整数 classType,代表后面要进行的操作类型。如果 classType 为 0,则退出循环。否则,根据 classType 的值选择不同的操作。
当 classType 为 1 或 2 时,使用未命名类进行操作,读入两个元素 a 和 b,并输出其差的绝对值。 当 classType 为 3 时,使用 Point 类进行操作,读入两个点 a 和 b,并输出两点之间的距离。 当 classType 为 4 时,使用 Time 类进行操作,读入两个时间 a 和 b, 并输出两个时间之间的时间间隔。 当 classType 为 5 时,使用 Date 类进行操作,读入两个日期 a 和 b, 并输出两个日期之间的日期间隔天数。
每个类都有一个构造函数,默认将类的成员变量初始化为 0。
每个类都有一个 set 函数,用于设置类的成员变量。
每个类都有一个重载的输入运算符 >>,用于从标准输入读入数据并设置类的各个成员变量。
除了未命名类外,其他三个类都重载了 - 运算符,用于计算类对象之间的差。
代码
#include<iostream> #include<cmath> using namespace std; // 定义Time类 class Time { private: int hh; // 时 int mm; // 分 int ss; // 秒 public: Time() { // 构造函数 hh = 0; mm = 0; ss = 0; } void set(int h, int m, int s) { // 设置 hh,mm,ss 的值 hh = h; mm = m; ss = s; } friend int operator-(Time, Time); // 友元函数,重载 - 运算符 friend istream& operator>>(istream&, Time&); // 友元函数,重载输入运算符 >> }; // 重载输入运算符 >> istream& operator>>(istream& set, Time& t) { set >> t.hh >> t.mm >> t.ss; // 从标准输入中读入数据 return set; } // 重载 - 运算符 int operator-(Time t1, Time t2) { int totalSecond1 = t1.hh * 3600 + t1.mm * 60 + t1.ss; // 计算总秒数 int totalSecond2 = t2.hh * 3600 + t2.mm * 60 + t2.ss; return totalSecond2 - totalSecond1; // 返回时间间隔 } // 定义Date类 class Date { private: int year; // 年 int month; // 月 int day; // 日 public: Date() { // 构造函数 year = 0; month = 0; day = 0; } void set(int y, int m, int d) { // 设置 year,month,day 的值 year = y; month = m; day = d; } friend int operator-(Date, Date); // 友元函数,重载 - 运算符 friend istream& operator>>(istream&, Date&); // 友元函数,重载输入运算符 >> }; // 重载输入运算符 >> istream& operator>>(istream& set, Date& d) { set >> d.year >> d.month >> d.day; // 从标准输入中读入数据 return set; } // 重载 - 运算符 int operator-(Date d1, Date d2) { int totalDay1 = d1.year * 365 + d1.month * 30 + d1.day; // 计算总天数 int totalDay2 = d2.year * 365 + d2.month * 30 + d2.day; return totalDay1 - totalDay2; // 返回日期间隔天数 } // 定义 Point 类 class Point { private: int x; int y; public: Point() { // 构造函数 x = y = 0; } void set(int a, int b) { // 设置 x 和 y 的值 x = a; y = b; } friend double operator-(Point, Point); // 友元函数,重载 - 运算符 friend istream& operator>>(istream&, Point&); // 友元函数,重载输入运算符 >> }; // 重载输入运算符 >> istream& operator>>(istream& set, Point& p) { set >> p.x >> p.y; // 从标准输入中读入数据 return set; } // 重载 - 运算符 double operator-(Point p1, Point p2) { return sqrt((1.0 * p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); // 返回点间距离 } // 主函数 int main() { int classType; while (cin >> classType) { // 循环读入类别 if (classType == 0) break; // 若为 0,则退出循环 switch (classType) { // 根据类别选择不同的操作 case 1: { // 整型元素 int a, b; cin >> a >> b; cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离 break; } case 2: { // 浮点型元素 double a, b; cin >> a >> b; cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离 break; } case 3: { // Point 类型 Point a, b; cin >> a >> b; cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离 break; } case 4: { // Time 类型 Time a, b; cin >> a >> b; cout << abs(b - a) << endl; // 输出 a 和 b 之间的时间间隔 break; } case 5: { // Date 类型 Date a, b; cin >> a >> b; cout << abs(b - a) << endl; // 输出 a 和 b 之间的日期间隔天数 break; } } } return 0; }
总结
该题结合重载
与函数模板
考察数据的间距问题,读者可躬身实践。
我是秋说,我们下次见。