Uva 230 - Borrowers

一.题目

题目链接:Uva230


二.思路

在阅读本篇源代码之前,建议大家先了解如何给map和set添加自定义排序,还有string的substr和find函数的用法。给出两篇博客给大家参考。

string类成员函数find/find_first_of用法详解

C++ STL中Map的按Key排序和按Value排序

然后讲讲我的思路吧:因为题目要求在进行相关操作之前就要有序,我用set<author,title>这样的pair集合来书目信息,定义符合题目要求的排序函数。信息录入完毕是集合已有序。然后R操作的时候也用一个这样的集合保存还书信息,先让还书的书目有序的好处是因为两个集合都是有序的,而在放书进书架的时候,字典序后的书一定会摆在字典需前的书的后面,这样子遍历一次图书馆的所存书目,就能找到所有要还的书目的位置。详情请见代码注释。


三.源代码

#include <iostream>
#include <map>
#include <set>
using namespace std;
//自定义set的排序函数使的插入是就按题目要求排序,所有信息录入完,整个数目已有序
struct Compare {
  bool operator()(const pair<string, string> &a,
                  const pair<string, string> &b) {
    if ((a.first).compare(b.first) < 0)  //先比较作者
      return true;
    if ((a.first).compare(b.first) == 0) { //作者相同,比较标题
      if ((a.second).compare(b.second) < 0)
        return true;
    }
    return false;
  }
};
set<pair<string, string>, Compare> stores;//用pair来保存数目信息
set<pair<string, string>, Compare> rt_bks;//用来保存还书的时候放书回书架的顺序
map<string, string> books; //用来完成title到author的映射
string author, title, line;
void show() {
  set<pair<string, string> >::iterator iter1 = rt_bks.begin();
  set<pair<string, string> >::iterator iter2 = stores.begin();
  if ((*iter1) == (*iter2)) {//先把第一个拿出来单独处理,如果相等,说明是放在第一本
    cout << "Put " << (*iter1).second << " first" << endl;
    iter1++;
    iter2++;
  } else
    iter2++;
  while (iter1 != rt_bks.end()) {
      //遍历stores,如果发现要放上的书的title和stores现在的一样,就把当前书的前一本书title记录下来
    if ((*iter1) != (*iter2))
      iter2++;
    else {
      cout << "Put " << (*iter1).second << " after " << (*(--iter2)).second<<endl;
      iter1++;//因为输出的时候iter2--了。所以要++两次
      iter2++;
      iter2++;
    }
  }
}
void splitAT(string l) {
    //将字符串中的author和title提取出来
  int index1 = l.find("\"", 1); //从第二个位置开始找第一个"的坐标
  title = l.substr(0, index1 + 1);
  //注意substr(n,m-n)子字符串是从n到m-n-1;不包括m-n,所以最后要+1
  int index2 = l.find(" by ");
  author = l.substr(index2 + 4, line.length() - (index2 + 4));
}
void splitT(string l) {
    //将字符串中的title提取出来
  int index = l.find("\"");
  title = l.substr(index, l.length() - index);
}
int main() {
  while (getline(cin, line) && line != "END") {
    splitAT(line);
    books.insert(make_pair(title, author));
    stores.insert(make_pair(author, title));
  }
  while (getline(cin, line) && line != "END") {
      //B和R操作记得更新相应的容器
    if (line[0] == 'B') {
      splitT(line);
      stores.erase(make_pair(books[title], title));
    }
    if (line[0] == 'R') {
      splitT(line);
      rt_bks.insert(make_pair(books[title], title));
      stores.insert(make_pair(books[title], title));
    }
    if (line[0] == 'S') {
        //输出完后记得清空记录还书的容器
      show();
      rt_bks.clear();
      cout<<"END"<<endl;
    }
  }
  return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值