STL总结心得

第八周开始学习使用STL,并做了一个图书管理系统。做图书管理系统的过程中遇到了很多问题,代码也修改了很多遍。在修改的过程中,虽然花了很多时间,但也从中吸取了很多经验。

第一次做图书管理系统时,从早上10点开始,第二天下午才完成。写代码时也确实也遇到了不少麻烦。

在听完老师的讲解之后,我意识到我写的程序存在很多问题。在第一次作业中,我对STL还不是很了解,没有充分利用STL,写代码时只考虑到功能能不能实现,没考虑效率和其他方面的问题。于是我进行了第一次修改。

  • 写日期类重载+运算符时,日期计算用效率低的for循环语句,听了老师的讲解后,就自己写了另一个效率比之前高的算法,这里我把数组a当作局部变量用。
CDate operator+(int d) {
		int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if ((year % 4 == 0 && year % 100 != 0) || (year % 4 == 0 && year % 400 == 0))
			a[2] = 29;
		day += d;
		while (day > a[month]){
			day -= a[month];
			month++;
			if (month > 12) {
				month -= 12;
				year++;
				if ((year % 4 == 0 && year % 100 != 0) || (year % 4 == 0 && year % 400 == 0))	//更新a[2]的值
					a[2] = 29;
				else
					a[2] = 28;
			}
		}
		return *this;
	}
  • 还有日期类的<<运算符重载,当时为如何对yyyy/mm/dd格式的日期进行处理,后来在网上找到了方法,输入的时候用字符类型(char)变量放在year和month中间,以及month和day中间,字符类型变量读取’/'字符,year、month、day就能读取到yyyy、mm、dd。
friend istream& operator >>(istream& in, CDate& d) {
	int a[13] = { 0,31,0,31,30,31,30,31,31,30,31,30,31 };
	char b;
	while (1) {
		in >> d.year >> b >> d.month >> b >> d.day;
		if (d.year >= 2020 && d.year <= 2021) {
			bool flag = (d.year % 4 == 0 && d.year % 100 != 0) || (d.year % 4 == 0 && d.year % 400 == 0);
			if (d.month == 2 && d.day <= 29 && flag)
				return in;
			else if (d.month == 2 && d.day <= 28 && !flag)
				return in;
			else if (d.day <= a[d.month])
				return in;
		}
	}
}
  • 在之前做增删查改时,是直接遍历vector找到符合条件的值,老师说这样做增删查改操作效率不高,在老师讲解之后用multimap建立索引。multimap里的元素是按key排序的,根据key查找时速度快。将要增删查改的元素放入key中,对应的vector下标放入value中,查找时以value的值确定被查找对象在vector中的位置,优化了增删查改的效率。
//修改前
void findBook(string ISBN) {
	int length = book.size();
	for (int i = 0; i < length; i++)
		if (book[i].getISBN() == ISBN) {
			book[i].showData();
			break;
		}
}

void deleteBook(string ISBN) {
	int length = book.size();
	vector<Book>::iterator iter = book.begin();
	for (int i = 0; i < length; i++, iter++)
		if (book[i].getISBN() == ISBN) {
			book.erase(iter);
			break;
		}
}
//修改后
multimap<string, int>::iterator findBookByISBN(string ISBN, bool flag) {
	multimap<string, int>::iterator it = bookISBN.find(ISBN);
	if (it != bookISBN.end() && flag)
		cout << book[it->second] << endl;
		return it;
}

void deleteBook(string ISBN) {
	multimap<string, int>::iterator it = findBookByISBN(ISBN, false);
	vector<Book>::iterator iter = book.begin();
	if (it != bookISBN.end()) {
		book.erase(iter + it->second);
		bookISBN.clear();
		bookName.clear();
		int size = book.size();
		for (int i = 0; i < size; i++) {		//重建multimap
			bookISBN.insert(make_pair(book[i].getISBN(), i));
			bookName.insert(make_pair(book[i].getName(), i));
		}
	}
}
  • 在之前做文件读写时,是通过调用getX()方法进行读写,但这样写代码太繁琐。在第一次修改中,我通过重载<<和>>运算符来进行输入输出的文件读写功能,大大简化了代码长度。
//修改前
void printBook(string file) {
	ofstream out(file.c_str());
	int length = book.size();
	for (int i = 0; i < length; i++)		//代码又臭又长又繁琐
		out << book[i].getISBN() << " " << book[i].getName() << " " << book[i].getEditor()
		<< " " << book[i].getPublish() << " " << book[i].getDate()->getDate() << " "
		<< book[i].getType() << " " << book[i].getTotal() << " " << book[i].getStore() << endl;
	out << -1 << endl;
	out.close(); 
//修改后
void printBook(string file) {
	ofstream out(file.c_str());
	int length = book.size();
	for (int i = 0; i < length; i++) {
		out << i + 1 << endl;
		out << book[i] << endl;		//代码简化
		for (size_t j = 0; j < book[i].getRecordSize(); j++) {
			Record r = book[i].getRecord(j);
			out << r << endl;		//代码简化
		}
		out << -1 << endl;
	}
	out << -1 << endl;
	out.close();
}
  • 第一次写这份作业时,我在操作类中创建了写文件的方法,但我没考虑到把写文件的方法加入到析构函数中,而是在main函数中调用。后来觉得在析构函数中调用更好些就做了修改。在写代码的过程中,为了节省时间,会复制代码中功能类似的部分,然后修改要替换的变量。但有两次复制后忘记修改,导致后面花了很多时间去查找出错的地方,这也算一次教训。对于借书、续借、还书的操作上,我第一次作业时把这三个功能写在了一个方法里,后来考虑到一个方法应该只实现一个功能,我就写成三个方法。

第二次修改我加入了模糊查询

  • 模糊查询:用find_if()进行查询。在写谓词函数时,不知道如何进行模糊查询,在网上查找资料后,发现strstr()函数可以实现模糊查询。该函数搜索一个字符串在另一个字符串里的第一次出现,并返回所搜索到字符串在另一个字符串中的位置,如果没有搜索到,则返回0(NULL)。

另外,组合查询和区间查询的功能之后再添加。

总之,这份作业让我花了很多时间去修改。通过这次作业,我对这部分的知识有了更深的了解,也巩固了过去的知识。在这过程中,也因为自己的失误导致程序出错,浪费了不必要的时间去排除问题,下次要避免类似情况再次发生。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值