习题5-8 图书管理系统 UVa230

1.题目描述:点击打开链接

2.解题思路:也是模拟题意,不过过程比较复杂;还好调试后一次AC了,不过当看到别人的代码时,无奈了。长度不到我的一半。。。仔细分析了参考代码,发现有如下值得学习的地方:1,巧用结构体,把borrowed,returned当做一本书的成员;2.利用stable_sort分别对作者和书名进行排序(这个我还真不会(⊙o⊙))3;把定义好的book当做模板运用到vector中,结合了vector的优点;判断书本的情况只需要看returned,borrowed的状态即可,大大简化了程序结构,很值得学习啊!

3.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<cassert>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<cstring>
#include<functional>
using namespace std;
const int maxn = 10000 + 10;
map<string,int>IDcache;  //记录作者的ID
vector<string>auth;      //存放每个作者的名字
vector<string>book[maxn];//每个作者自己的书
vector<int>shelf[maxn]; //模拟书架上的书籍
vector<int>back[maxn];//存储归还的书的位置
vector<int>borrow[maxn];//存放借走的书的位置
int arr[maxn];          //存放排序后的作者ID的编号
int len;                //存放arr数组的长度

int ID(string&str)//给每个作者分配一个ID
{
	if (IDcache.count(str))
		return IDcache[str];
	auth.push_back(str);
	return IDcache[str] = auth.size() - 1;
}
void find_book(string s, int&p,int&h)//寻找书的位置,第p个作者的第h本书
{
	for (p = 0; p < len;p++)
	for (h = 0; h < book[p].size();h++)
	if (book[p][h] == s) return;
}
void take_away(int p, int h)
{
	borrow[p].push_back(h);
	shelf[p][h] = 0;
}
void bring_back(int p, int h)
{
	back[p].push_back(h);
	sort(back[p].begin(), back[p].end());
	for (int i = 0; i < borrow[p].size();i++)
	if (borrow[p][i] == h)
	{
		borrow[p].erase(borrow[p].begin() + i); //删除借书的记录
		break;
	}
}
void before(int&p, int&h)//寻找它的前一本书的位置
{
	int m = p, n = h;
	if (p == 0 && h == 0) return;
	for (;;)
	{
		if (h == -1)
		{
			p--;
			h = shelf[arr[p]].size() - 1;
		}
		if (p == 0 && h == 0)
		if (shelf[arr[p]][h] > 0) return;
		else
		{
			p = m;
			h = n;
			return;
		}
		if (shelf[arr[p]][h] > 0)return;
		h--;
	}
}
void print()
{
	for (int i = 0; i < len; i++)
	if (!back[arr[i]].empty())
	{
		int p, h;
		int len = back[arr[i]].size();
		for (int j = 0; j <len; j++)
		{
			p = i;
			h = back[arr[i]][j];
			before(p, h);
			if (p == i&&h == back[arr[i]][j])没找到前一本书,说明这是第一本书
				cout << "Put " << book[arr[p]][h] << "first" << endl;
			else
				cout << "Put " << book[arr[i]][back[arr[i]][j]] << "after " << book[arr[p]][h].substr(0, book[arr[p]][h].length() - 1) << endl;
			shelf[arr[i]][back[arr[i]][j]] = 1;
		}
		back[arr[i]].clear();//该作者的所有书归还后清空归还记录
	}
	cout << "END" << endl;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	string line;
	while (getline(cin, line) && line != "END")
	{
		stringstream ss(line);
		string buf;
		string st,sr;
		while (ss >> buf)
		{
			if (buf == "by")break;
			st += buf;
			st += " ";
		}
		while (ss >> buf)
			sr += buf;
		book[ID(sr)].push_back(st);
	}
    len = auth.size();
	sort(auth.begin(), auth.end());//对作者进行排序
	memset(arr, 0, sizeof(arr));
	for (int i = 0; i < len; i++)
		arr[i] = IDcache[auth[i]];
	for (int i = 0; i < len; i++)
		sort(book[i].begin(), book[i].end());//对每个作者的书进行排序
	for (int i = 0; i < len;i++)
	for (int j = 0; j < book[i].size(); j++)
		shelf[i].push_back(1);//判断书架上书的状态
	string s1, s2;
	while (getline(cin,line))
	{
		stringstream ss(line);
		string ct,s1,s2;
		while (ss >> ct)
		{
			s1 = ct; 
			break;
		}
		while (ss >> ct)
		{
			s2 += ct;
			s2 += " ";
		}
		int p,h;
		if (s1[0] == 'S') print();
		find_book(s2, p,h);
		if (s1[0] == 'B') take_away(p,h);//借书
		if (s1[0] == 'R') bring_back(p,h);//还书
		if (s1[0] == 'E')break;
	}
	return 0;
}

(参考代码)长度是我的一半,但写的非常精彩,值得学习的地方特别多。

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

class book   //定义结构体book
{
	public:
		book( string t, string a ) { author = a; title = t; borrowed = returned = false; }
		bool borrowed, returned;//把borrowed,returned当做书本的成员
		string author, title;
};
vector<book> all;
string in, command, req;

void shelve(), borrow(), back();
bool cmpa( book a, book b ){ return ( a.author < b.author ); }//按照作者排序
bool cmpt( book a, book b ){ return ( a.title < b.title ); }//按照书名排序

int main()
{
	while( getline( cin, in ) && in != "END" )
		all.push_back( book( in.substr( 0, in.find_last_of( "\"" ) + 1 ), 
					in.substr( in.find_last_of( "\"" ) + 1 ) ) );
	stable_sort( all.begin(), all.end(), cmpt );//分别对两种情况进行排序
	stable_sort( all.begin(), all.end(), cmpa );

	while( cin >> command )
		if( command == "BORROW" )
			cin.get(), borrow();
		else if( command == "RETURN" )
			cin.get(), back();
		else if( command == "SHELVE" )
			cin.get(), shelve();
}

void shelve()
{
	for( int i = 0, j; i < all.size(); ++i )
		if( all[ i ].returned == true )//书本已经归还
		{
			for( j = i; j >= 0; --j )
				if( all[ j ].borrowed == false )//找到待放回书架的书的前一本书的位置
					break;
			if( j == -1 )
				printf( "Put %s first\n", all[ i ].title.c_str() );//转换成标准C输出
			else
				printf( "Put %s after %s\n", all[ i ].title.c_str(), all[ j ].title.c_str() );
			all[ i ].borrowed = all[ i ].returned = false;//放回后,将状态重置
		}
	cout << "END\n";
}

void borrow()
{
	getline( cin, req );
	for( int i = 0; i < all.size(); i++ )
		if( all[ i ].title == req )
		{
			all[ i ].borrowed = true;
			return;
		}
}

void back()
{
	getline( cin, req );
	for( size_t i = 0; i < all.size(); i++ )
		if( all[ i ].title == req )
		{
			all[ i ].returned = true;
			return;
		}
}


你可能感兴趣的:(uva)