作业要求:
为Date类实现如下成员:
1. 构造器,可以初始化年、月、日。
2. 大于、小于、等于(> 、< 、==)操作符重载,进行日期比较。
3. print() 打印出类似 2015-10-1 这样的格式。
然后创建两个全局函数:
1. 第1个函数 CreatePoints生成10个随机的Date,并以数组形式返回;
2. 第2个函数 Sort 对第1个函数CreatePoints生成的结果,将其按照从小到大进行排序。
最后在main函数中调用CreatePoints,并调用print将结果打印出来。然后调用Sort函数对前面结果处理后,并再次调用print将结果打印出来。
date.h
#ifndef __MYDATE__
#define __MYDATE__
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
class Date;
void CreatePoints(Date* date, const int& n);
void Sort();
class Date
{
public:
Date(int y = 0, int m = 0, int d = 0) :year(y), month(m), day(d) { } //析构函数
bool operator >(const Date&);
bool operator <(const Date&);
bool operator ==(const Date&);
void print() { cout << year << '-' << month << '-' << day; }
private:
int year;
int month;
int day;
friend void CreatePoints(Date* date, const int& n);
};
//成员函数
inline bool
Date::operator >(const Date& r)
{
return this->year > r.year || (this->year == r.year&&this->month > r.month)
|| (this->year == r.year&&this->month == r.month&&this->day > r.day);
}
inline bool
Date::operator <(const Date& r)
{
return this->year < r.year || (this->year == r.year&&this->month < r.month)
|| (this->year == r.year&&this->month == r.month&&this->day < r.day);
}
inline bool
Date::operator ==(const Date& r)
{
return this->year == r.year && this->month == r.month&&this->day == r.day;
}
//随机生成1900-2017年之间的n个日期,并以数组形式返回
void CreatePoints(Date* date, const int& n)
{
srand((unsigned)time(NULL)); //初始化种子
for (int i = 0; i < n; ++i)
{
date[i].year = rand() % 117 + 1900;//随机生成年份
date[i].month = rand() % 12 + 1;//随机生成月份
switch (date[i].month) //随机生成天数
{
case 2://2月份考虑是否为闰年
if ((date[i].year %4==0 && date[i].year % 100 != 0) || date[i].year % 400 == 0)
{
date[i].day = rand() % 29 + 1;
break;
}
else
{
date[i].day = rand() % 28 + 1;
break;
}
case 4:
date[i].day = rand() % 30 + 1;
break;
case 6:
date[i].day = rand() % 30 + 1;
break;
case 9:
date[i].day = rand() % 30 + 1;
break;
case 11:
date[i].day = rand() % 30 + 1;
break;
default:
date[i].day = rand() % 31 + 1;
break;
}
}
}
//冒泡排序
void Sort(Date* date, const int& n)
{
Date temp;
for (int i = 0; i < n - 1; ++i)
{
for (int j = 0; j < n - i - 1; ++j)
{
if (date[j] > date[j + 1])
{
temp = date[j];
date[j] = date[j + 1];
date[j + 1] = temp;
}
}
}
}
#endif //__MYDATE__
date_test.cpp
#include <iostream>
#include "date.h"
#define N 20
using namespace std;
int main()
{
Date* date = new Date[N];
cout << "Please enter the number:" << endl;
int n;//随机生成年份的个数,n<=20
cin >> n;
CreatePoints(date, n);//随机生成n个日期
cout << "Before sort:" << endl;
for (int i = 0; i < n; ++i)
{
date[i].print();
cout << endl;
}
Sort(date, n);//对随机生成的日期进行排序
cout << "After sort:" << endl;
for (int i = 0; i < n; ++i)
{
date[i].print();
cout << endl;
}
delete[] date;
return 0;
}
作业小结:
这次的作业问题有点多,
第7行: 不要在头文件中写using namespace std;,容易造成命名空间污染;点击打开链接
第9行: 并不需要class Date的前置声明
第10行: 对于const int& n,没有必要对int参数进行传引用
第11行: 从逻辑上讲,sort函数不应当包含在date.h头文件中
第20行: print函数不修改成员变量,应修改为常量成员函数
第31、38行:
逻辑上存在冗余,this->year < r.year || (this->year == r.year&&this->month < r.month) || (this->year == r.year&&this->month == r.month&&this->day < r.day);
比如假设this->year是大于r.year的,那么代码会连续测试this->year == r.year才能返回假,是没有必要的。
我的写法如下:
if (lhs.getYear() < rhs.getYear()) return true;
if (lhs.getYear() > rhs.getYear()) return false;
if (lhs.getMonth() < rhs.getMonth()) return true;
if (lhs.getMonth() > rhs.getMonth()) return false;
return lhs.getDay() < rhs.getDay();
检测不符合时能及早返回,逻辑上没有冗余,仅供参考。
第58-85行的switch写法:
首先,对于4,6,9,11的情况,应采用用fall through的写法;default的情况最好显式写出避免出现歧义,因为一旦上面的case数字写错了,default就不是你想的情况了,建议将default用于出错处理;
其次,最好将月份的数字存储起来,采用查表法加快查询速度;
第10行: 对于const int& n,没有必要对int参数进行传引用
第11行: 从逻辑上讲,sort函数不应当包含在date.h头文件中
第20行: print函数不修改成员变量,应修改为常量成员函数
第31、38行:
逻辑上存在冗余,this->year < r.year || (this->year == r.year&&this->month < r.month) || (this->year == r.year&&this->month == r.month&&this->day < r.day);
比如假设this->year是大于r.year的,那么代码会连续测试this->year == r.year才能返回假,是没有必要的。
我的写法如下:
if (lhs.getYear() < rhs.getYear()) return true;
if (lhs.getYear() > rhs.getYear()) return false;
if (lhs.getMonth() < rhs.getMonth()) return true;
if (lhs.getMonth() > rhs.getMonth()) return false;
return lhs.getDay() < rhs.getDay();
检测不符合时能及早返回,逻辑上没有冗余,仅供参考。
第58-85行的switch写法:
首先,对于4,6,9,11的情况,应采用用fall through的写法;default的情况最好显式写出避免出现歧义,因为一旦上面的case数字写错了,default就不是你想的情况了,建议将default用于出错处理;
其次,最好将月份的数字存储起来,采用查表法加快查询速度;
排序函数可以使用标准库函数;