Uva230
Posted Western_Trail
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Uva230相关的知识,希望对你有一定的参考价值。
题目地址: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=166
题意:
就是输入一系列书本名和作者名,然后输入命令模拟借书和还书,再输出归还的书的摆放位置。要求有两点:
- 需要对归还的书做特殊排序处理:作者名相同,则书本按书名从小到大排序;否则书本按作者名大小排序
- 需要归还的书的位置前面没有书籍时,需要特殊处理
具体的要求还需参见原题
思路分析:
- 首先还是得解决输入的问题:使用
getline()
读取完整的一行.再使用substr()
截取书名和作者名即可。 - 再之后就是做数据的存储工作,使用一个不定长数组
vector<int>
容器存储所有书本名,使用map<string,结构体>
存储书名到"状态status
"的映射以便模拟借书,还书的过程。 - 之后就是模拟命令,还是使用
getline()
做输入处理,并且改变相应需处理书本的状态。完成上述步骤后,循环遍历所有的书本,查找书本的状态。如果是需归还的书,则查找此书之前的所有书本的状态,如果有找到状态为未借的书,则把书放到该书后面,若没有找到则把需归还的书放在"first"位置。归还之后,还需要对归还书的状态改为"未借"即(status = 1)。
代码:
#include <iostream>
#include <set>
#include <vector>
#include <sstream>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
struct Book{
string Author;
int status;
};
map<string, Book> books;
vector<string> book_name;
void sperate_book_aut(string s,string& book,string& author){ //分离输入为书名和作者名
int k = s.find("\"",1);
int t = k + 5; //t为作者的第一个字母下标
book = s.substr(0,k+1);
author = s.substr(t);
}
bool compare(string p,string q){ //重载小于
if(books[p].Author == books[q].Author) return p < q;
else return books[p].Author < books[q].Author;
}
int main(void){
string s,book,author;
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
while(getline(cin,s) && s != "END"){
sperate_book_aut(s,book,author); //分离书本和作者名
book_name.push_back(book);
books[book].Author = author;
}
sort(book_name.begin(),book_name.end(),compare); //对书名做"特定"排序
//初始化书本状态
for(int i = 0;i < book_name.size();i++){
books[book_name[i]].status = 1;
}
string cmd;
while(cin>>cmd && cmd != "END"){
if(cmd == "BORROW"){
getchar();
getline(cin,book);
books[book].status = 0;
}
if(cmd == "RETURN"){
getchar();
getline(cin,book);
books[book].status = -1;
}
if(cmd == "SHELVE"){
for(int i = 0;i < book_name.size();i++){
if(books[book_name[i]].status == -1){
int j;
for(j = i;j >= 0;j--)
if(books[book_name[j]].status == 1) break;
if(j > -1) cout<<"Put "<<book_name[i]<<" after "<<book_name[j]<<"\n";
else cout<<"Put "<<book_name[i]<<" first"<<"\n";
books[book_name[i]].status = 1;
}
}
cout<<"END"<<"\n";
}
}
return 0;
}
心得体会:
还是没有独立做出来,这几天训练C++ STL感觉还是没有做到融会贯通,map,vector,set不会组合使用,什么时候该用什么容器得仔细琢磨否则就直接影响解题效率。就本题而言,因为书本数目未知,所以可以使用不定长数组vector
存储。至于映射map
刚开始实在没想到为什么要用map
来解这道题,后来想想要存储书名到书本状态的映射关系也就明了了,不可能用数组去存储这种状态吧,最好的方法就是用map<string,int>
,可以简单地把map看成一个"数组",特殊就特殊在map"数组"下标不是整数,而可以是字符串,值就是存储的映射关系。本题的map键值也可以不是结构体,但是这样的话就必须再定义一个map<string,string>
去存储书名到作者名的映射(因为在本题排序中要用到),当然这样做也同样简单。
以上是关于Uva230的主要内容,如果未能解决你的问题,请参考以下文章
UVA 230 Borrowers (STL 行读入的处理 重载小于号)
习题5_8 图书管理系统(Borrowers, ACM/ICPC World Finals 1994, UVa230)
七个办法只有一个有效:200 PORT command successful. Consider using PASV.425 Failed to establish connection.(代码片段