C++课程设计详解-12306的模拟实现

目录

设计思路... 3

思路分析:.... 3

数据组织:.... 4

具体功能实现过程... 4

管理端具体功能实现:.... 4

用户端具体功能实现:.... 5

调试截图和调试过程中遇到的问题及改进:... 12

时间类.... 12

站台类.... 14

列车站点类.... 16

列车类.... 17

车票类.... 19

用户数据类.... 21

查询类:.... 22

管理端.... 28

设计体会与小结... 29

 

 

 

设计思路

设计一个系统,首先要考虑实现什么功能,需要怎样组织数据。所以先通过查询12306,知道了12306最终要实现:

 

其次在分析实现方式,或者说自己以什么方式实现:

思路分析:

站台中不能存车次的所有信息,那样就会站台包括车次,车次包括站台,循环定义,空间无限大,编译应该是不通过,利用车次与车站名是唯一的,所以站台与列车信息种只存彼此的名字即可。而对于车票,因为一个月最多有31天,开一个31天的int储存,这样今天20号,那么输入11号的话绝对是下个月的,因为不可能买今天之前的票,21号的话绝对是这个月的21号,因为最多买后30天的票。余票的话,因为车站发售的票,不一定是实际可乘坐的余票,所以在每个站台存车次的余票为该站台最多可发售的余票,而火车种存有每个站台实际可卖的余票,乘车区间的火车实际余票最小值与该站台最多发售余票取最小值即为该乘车区间可发售的余票。

在在个系统中一定会有时间,应写一个时间类,时间类包括年月日时分,get/set函数,通过两个时间类计算停靠时间,这里会发现,任何一辆高铁夜间都是不行车的,所以不会出现跨天的可能,其实也不会出现超过一小时的,所以返回分钟即可。因为要存日志文件,所以要判断记录中的出行时间是否小于当前时间,要是小于就代表已经出行,需要生成日志文件,而不继续存在文件的数据中,这里用了流对象的储存文件名参数可以为一个string变量,可以自定义。最后便于从文件中读取数据,重载了>>与<<运算符。

详细的站台数据应该包括站台名,站台包括的车次及余票,也应该包括某辆车到该站点的时间信息等,将站台分为两个类,第一个是时间得站台包括车次信息,另一个是组合于列车类的站台信息包括时间参数等及其打印函数。

为了能够生成记录,以及查询已购的票,设置了一个车票类或称record类,包括车站、车次信息,出发、到达时间,购票人的身份证,同一张车票将人车于站台全部联系起来,为了使车票有自己唯一的编号,通过一个生成名字的函数,基于车次身份证出发时间生成,这样生成的车票名确定且唯一。

用户信息类,用户需要验证身份信息,所以必须需要一个类来储存身份信息,应该包括登陆账号手机号,身份证号,姓名,密码,是否为黑名单,已买到的票可以通过向量保存,储存车票名即可。也许打印身份信息函数,修改手机号函数,改密码函数。

数据组织:

通过前面的实现思路,数据组织方式也很明确,数据类共计6个分别是①时间类、②站台类、③列车站点类、④列车类、⑤车票类、⑥用户数据类。所有数据类都重载类输入输出运算符。操作了类共计3个分别是①查询类、②用户端类、③管理端类。

具体功能实现过程

管理端具体功能实现:

增删查改站点:

查,可以继承用户端,用户的操作的管理员的都能做,除了买票退票,但是除此之外的所有有功能在管理端都可以进行于是用户端继承查询类,而修改站点可以简化为新建一个站点,删除旧站点。

增删查改车次:

查也可以继承,增可以写创建函数,删写删除函数,在列车数据vector中遍历查找要删除的车次,进行实删。

用户端具体功能实现:

查车票:

查询票需要三个参数,初始站,目的站,乘车日期,此时系统会打印那天所有经过两个站点的车次信息,是否有票无票都会打印,实现方法,将起始站经过的所有车次于目的站所经过车次对比,相同的保留,可以通过set将车次名放入,车次名在我国意一一对应车次,当放不进set去之后,用vector保存,则vector中的   存储车次为可到达车次。通过遍历取最小值获得余票,通过数据里的打印函数打印列车信息。

         bool Baseque :: cxyp(string a,string b,int riqi)

{

    auto w=station[natosta[a]].quecheci();

    auto v=station[natosta[b]].quecheci(); //vector<pair<string,int>> checi

    set<piao>tem;

    vector<piao>temp;

    temp.clear();

    for(auto po=w.begin();po!=w.end();po++) tem.insert(*po);

    for(auto po=v.begin();po!=v.end();po++)

    {

        if(tem.insert(*po).second==0) temp.push_back(*po);

    }

    if(temp.size()==0)

    {

        cout<<"No ticket"<<endl;

        return 0 ;

}

int  Train::cxyp(string  a,string  b,int c)

{

    bool flag=0;

    int mini=0x3f3f3f3f;

    for(auto po=station.begin();po!=station.end();po++)

    {

        if(po->getsta()==a) flag=true;

        if(flag) mini=min(mini,po->getpiao(c));

        if(po->getsta()==b) break;

    }

    return mini;

}

车站车次查询:

应该有三个参数出发时间段,到达时间段,车站。此时系统会打印,在出发时段或到达时段通过该站点的车次,通过基类的get函数,获得经过该站点的车次名称,在操作类中找到对应的车次信息,判断他出发时间和到达时间,符合要求打印车次信息。

void Baseque ::czcc(string a,int b,int d)

{

    vector<piao>w=station[natosta[a]].quecheci();

    for(auto po=w.begin();po!=w.end();po++)

    {

       vector<Zt> q= train[checitotrain[po->name]].getzt();

       for(auto pi=q.begin();pi!=q.end();pi++)

       {

            if(a==pi->getsta())

             {

                 if(pi->getarr()==b||b==0||pi->getlea()==d||d==0)

                 {

                      cout<<po->name<<endl;

                     if(pi!=q.begin())

                     {

                            q.begin()->printl();

                            if(pi==q.end()-1)

                            {

                                (q.end()-1)->printa();

                               //cout<<2<<endl;

                                    cout<<endl;

                            }

                            else

                            {

                                pi->print();

                                  //   cout<<endl;

                                (q.end()-1)->printa();

                               //  cout<<3<<endl;

                            }

                             cout<<endl;

                     }

                     else

                     {

                             q.begin()->printl();

                             (q.end()-1)->printa();

                             cout<<endl;

                     }

                     cout<<endl;

                 }

             }

       }

    }

}

车次查询:

应该有一个参数,车次名,车次每天的都是重复的一样的,所以只输入车次名即可,输入车次名得到对应的车次的数据进而借助的列车的print函数打印列车的详细信息。      

 void Baseque ::cxcx(string a)  //车次查询

{

    if(checitotrain.find(a)==checitotrain.end())

    {

        cout<<"NO Train"<<endl;

        return ;

    } //查不到不打印

    vector<Zt> w=train[checitotrain[a]].getzt();

    for(auto po=w.begin();po!=w.end();po++)

    {

        cout<<station[natosta[po->getsta()]].getname()<<' ';

        if(po!=w.begin()&&po!=w.end()-1)

        {

            po->print();

           //cout<< po->getleave().first<<' '<<po->getleave().first;

        }

          else if(po==w.begin())

          {

               cout<< po->getleave().first<<' '<<po->getleave().first;

          }

          else   cout<<po->getarrive().first<<' '<< po->getarrive().second<<' ';

    }

    cout<<endl;

}

购票:

购票需要传四个参数,但是在查询中已经输入了三个参数,所以只用再选择车次即可购票。购票为对某个乘车区间内的要出发那天车票进行自减操作,除此之外还要对起始站站台内这个车次的那一天的余票也要减1;实现方式调用站台类的函数,跟火车类的函数,通过遍历对火车的区间操作。此外要注意,是否为黑名单,是否为买的票超过了5张。

bool Client::buytic(string a,string b,int c) //先查后买,查不到不能买。

{

    if(!(cxyp(a,b,c))){cout<<"无票"<<endl;return 0;}

    if(user[now].getboupiao()>5||user[now].getban())

    {

        cout<<"购票限制"<<endl;

        return 0;

    }

   else

    {

        string id;

        cin>>id;

        pair<int,int>www=train[checitotrain[id]].buytic(a,b,c);

        station[natosta[a]].buytic(a,c);

        Time no1,no2;

        no1.loadtime();

        no2.loadtime();

        no2.seth(www.first,www.second);

        if(no2.getday()<c) no2.setmonth(no2.getmonth()+1);

        Tick tem(no1,no2,a,b,now2,id);

        tick.push_back(tem);

        hashtotick.insert(make_pair(tem.getname(),tick.size()-1));

        user[now].buytic(tem.getname());

    }

    return 1;

}

退票:

退票需要先查询自己买到了什么票,然后在进行选择要推动票,实现方式与买票实现方式相同(某个区间的票+1) ,火车开了之后,不能退票,但是可以改签。

void Client::reback() //先查后买,查不到不能买。

{

  printmp();

 string id=now2;

 int n;

 cout<<"退哪一张票"<<endl;

 cin>>n;

 n=n-1;

 auto ww=user[now].gettic();

 string a=tick[ hashtotick[ww[n]]].getfrom();

 string b=tick[ hashtotick[ww[n]]].getto();

 int c=tick[ hashtotick[ww[n]]].getlea().getday();

 train[checitotrain[id]].reback(a,b,c);

 string e=tick[ hashtotick[ww[n]]].getna();

 station[natosta[a]].rebac(e,c);

  // tick.erase(hashtotick[ww[n]]+tick.begin());

}                         

改签:

相当于退票+重新购票,不过改签的关键为能否找到合适的票进行改签,如果没找到要改签的的票,这样的改签无意义,所以相当于先购票后买票,购票失败等于改签失败,所以购票的返回值为bool类型,购票成功返回1否则返回0。

void Client::replacetic()

{

    string a,b,id;

    int c;

    cin>>a>>b>>c;

  if(  buytic(a,b,c))

   {

        cin>>a>>b>>c;

        reback();

   }

}

换乘:

两个城市不能接联通,需要借助最短路,需要找出中转城市,但是鉴于京沪线的所有站点都有车次经过,且换乘实现有难度,不考虑这个功能。

查询修改个人信息:

通过写一个用户信息类,一方面用于信息查询,另一方面用于登陆。这样再通过用户信息类的打印函数,即可完成身份信息的查询。

                     void Client::printmp()

                    {

                        auto ww=user[now].gettic();

                          if(ww.size()==0)return ;

                        for(auto po=ww.begin();po!=ww.end();po++)

                        {

                           cout<<po-ww.begin()+1<<endl;

                            tick[ hashtotick[*po]].print();

                        }

                    }

列车、站台数据文件读写:

void Baseque::load()

{

     int x,y,n;

    ifstream in1("station.txt",ios::in);

    in1>>n;

     while(    n--)

     {

          Station tem1;

               in1>>tem1;

if(tem1.getname()=="$$") continue;

            station.push_back(tem1);

             natosta.insert(make_pair(tem1.getname(),station.size()-1));

     }

     in1.close();

     ifstream in2("train.txt",ios::in);

     in2>>n;

     while(n--   )

    {

        Train tem2;

        in2>>tem2;

        if(tem2.gettr()=="$$") continue;

        train.push_back(tem2);

        checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));

    }

    in2.close();

}

void Baseque::save()

 {

  ofstream out1("station.txt",ios::out);

  out1<<station.size()<<endl;

     for(auto po=station.begin();po!=station.end();po++)

        out1<<*po<<endl;

    out1.close();

    ofstream out2("train.txt",ios::out);

    out2<<train.size()<<endl;

     for(auto po=train.begin();po!=train.end();po++)

        out2<<*po<<endl;

        out2.close();

 }

车票(记录)和用户数据读写及日志文件的形成:

void Client::load2()

{

    ifstream in("user.txt",ios::in);

    int n;

    if(!in) return ;

    in>>n;

    while(n--)

    {

        User tem;

        in>>tem;

        if(tem.getphone()=="&&&")continue;

        user.push_back(tem);

        idtouse.insert(make_pair(tem.getname(),user.size()-1));

    }

    in.close();

    ifstream in2("tick.txt",ios::in);

    if(!in2) return ;

    in2>>n;

    while(n--)

    {

        Tick tem;

        in2>>tem;

        if(tem.getname()=="$$$") continue;

        tick.push_back(tem);

        hashtotick.insert(make_pair(tem.getname(),tick.size()-1));

    }

    in.close();

}

void Client::save2()

{

    ofstream out("user.txt",ios::out);

    out<<user.size()<<endl;

    for(auto po=user.begin();po!=user.end();po++) out<<*po<<endl;

    out.close();

    ofstream out2("tick.txt",ios::out);

    stringstream sss;

    Time now;

    now.loadtime();

    string temp;

    sss<<now.getyear()<<"年"<<now.getmonth()<<"月"<<now.getday()<<"日";

    sss>>temp;

    ofstream out3(temp,ios::out);   //做过的车,就存到日志文件不在读取。

    int sum=0;

    for(auto po=tick.begin();po!=tick.end();po++)

    {

        if(now>po->getlea())

        {

            out3<<*po<<endl;

        }

        else sum++;

    }

    out3.close();

    out2<<sum<<endl;

    for(auto po=tick.begin();po!=tick.end();po++)

    {

        if(now>po->getlea()) continue;

        out2<<*po<<endl;

    }

    out2.close();

}

设计体会与小结

课程设计中遇到了一个文件读写的问题,让我很棘手,从来不会觉得自己是文件对不上数据读取出现问题,开始寻找问题,一开始以为是文件流写错了,开始检查检查了好几遍,最后该手动输入但是还是有问题,我觉的可能是vector的内存空间不够了,输入指针失效了,但是在CSDN只是看到了这个问题,并没有找到合适的解决方法,系统就到了瓶颈期,只要这个文件读不进去,整个系统都完蛋了,开始发荒,再检查一遍还是不对,这个时候还是没察觉到自己文件有问题,回过头去重新测重载输入流,测试发现正确,于是我觉得我的文件出现了问题,去检查数据文件,数据文件看上去没问题,发现还是不能正常读入,于是又回过头用之前数据类的重载的输入输出流测数据,发现有一组数据两个数之间少了空格,于是输入int的位置放上了string,才导致错误,经过修改后程序终于可以顺利运行,但是就因为一个数据文件,却耽误了整整一天,这对于这段段代码来说,一天不是什么问题,但是如果真的到了就业,还是犯这种粗枝大叶的毛病的话,那可能不是耽误自己,而是耽误一个团队,从一点小事就反映出,敲代码是一个谨慎的工作,可能一字之差,带了结果影响巨大,在这次课程设计中,我通过调代码的痛苦过程铭记谨小慎微的心态,而不是抱着一种我觉得这样没错,这样跟我想的一样,而不真的去检验,也没有考虑的那么全面,这是我在课程设计中最大的教训,也是最大收获。

课程设计中又回顾了很久之前用过的字符串流,很长时间没有使用确实略显生疏,但是在摸索下还是上手很快,其他也使用很多的重载运算符,尤其是对于输入输出流的重载,这对于文件读写来说甚是方便。最重要的是学习了一种文件读写的方式,ifstream于oftream的open参数是一个字符串,这是之前没有发现的事情,只是知道第一个参数可以传“参数”,但是却忽略了双引号就是一个string,在查阅记录无果后,询问老师,老师给出了方法,在看了源码后发现这里就是一个string,通过传一个string 参数就可以动态的打开一个文件,也可以动态生成任意文件名储存到任意路径。

       通过自己写代码发现,思路设计的时候总是眼高手低,觉得这个可以这样实现,那个可以那样实现,但是等到真的实现的时候却发现他并不是那么轻易的就会被实现,所以设想哥实现了具体操作的时候是有很大的出入的,所以应该在设想的时候就要具体的去设计一些功能,而不是浅显的觉得这个东西用什么可以去实现,比如买票,而买票的,厄设计的时候当时想的整个区间都减一,但是却没有想到这个票的站台票和车次车次上的余票是分开的,而且操作的时候也要分两步进行操作。

代码中的不足之处是没有写出换乘,一是换乘的实现过程比较复杂,二是数据文件不太支持,所以没有写出来是比较遗憾的,没有把算法和程序结合,这点也是不足之处,需要改进!

 

#include<bits/stdc++.h.>
using namespace std;
class Time
{
    int  year,month,day;
    int hour,mini;
public:
    Time(){loadtime();}
    Time(int y,int m,int d):year(y),month(m),day(d){};   //用于车票生成。
    void loadtime();    //定义时间获取函数,用于获取买票时间,直接从系统读入;
    friend istream & operator>>(istream &in,Time & a);
    friend stringstream & operator>>(stringstream &in,Time & a);
    friend ostream & operator<<(ostream &out,Time & a); //排序函数,用于车票信息的储存;
    bool operator <(const Time &d)const;   //重载小于号,用于数据时间排序,不需要修改数据const
    int judge() const;  //判断是否为闰年;
    int judge(int year) const ;//写一个有参的判断函数;
    Time operator +(int  a) ;   //重载加号,用于放票;
     bool operator ==(Time & a) ; //判断是否为一天;
    friend int operator -(Time a,Time b);  //计算两段时间间隔;
    void print()const;//打印时间;
    bool operator>(Time&a);
    int getday(){return day;}
    int getmonth(){return month;}
    int getyear(){return year;}
    int gethour(){return hour;}
    void set();
    void setmonth(int a){month=a;}
    pair<int,int> tksj(Time&b); //停靠时间
    void seth(int a,int b){hour=a;mini=b;}
};
 bool Time ::operator>(Time&a)
 {
      return (year!=a.year)?year>a.year:month!=a.month?month>a.month:day!=a.day?day>a.day:0;
 }
bool Time::operator ==(Time & a)
{
    return (year!=a.year)?0:month!=a.month?0:day!=a.day?0:hour!=a.hour?0:mini==a.mini;
}
Time Time::operator +(int  a)
{
    int m[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    day+=a;
    int flag=1;
   while(day>m[month]){
        if(month==2){
            if(day>m[month]+judge()){
                day-=m[month]+judge();
                month++;
            }
        }
        else {
            day=day-m[month];
            month++;
        }
        if(month>12){
        month-=12;
        year++;
    }
   }
}
int operator -(Time a,Time b)
{
    int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
    int yeardays[2] = { 365,366 };
    int sumdays=0;
   if (a.year == b.year&& a.month == b.month){
        sumdays = b.day - a.day;
    }
    else
        if (a.year == b.year){
            sumdays += monthdays[a.judge(a.year)][a.month-1] - a.day;
            for (int i = a.month; i < b.month-1; i++)
                sumdays += monthdays[a.judge(a.year)][i];
            sumdays += b.day;
        }
        else{
            sumdays += monthdays[a.judge(a.year)][a.month-1] - a.day;
            for (int i = a.month; i < 12; i++)
                sumdays += monthdays[a.judge(a.year)][i];
            for (int i = a.year + 1; i < b.year; i++)
                sumdays += yeardays[a.judge(i)];
            for (int i = 0; i < b.month - 1; i++)
                sumdays += monthdays[a.judge(b.year)][i];
            sumdays += b.day;
        }
    return sumdays;
}
int Time::judge() const{
        if(year % 4 == 0 && year %100 != 0 ||year % 400 == 0) return 1;
        else return 0;
}
int Time::judge(int year) const{
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)return 1;
    else  return 0;
}
void Time::loadtime(){
    time_t rawtime;
    struct tm *ptminfo;
    time(&rawtime);
    ptminfo = localtime(&rawtime);
    year=ptminfo->tm_year + 1900;
    month=ptminfo->tm_mon + 1;
    day=ptminfo->tm_mday;
    hour=ptminfo->tm_hour;
    mini=ptminfo->tm_min;
}
istream & operator>>(istream &in,Time & a){
    in>>a.year>>a.month>>a.day>>a.hour>>a.mini;
    return in;
}
ostream & operator<<(ostream &out,Time & a)
{
    out<<a.year<<" "<<a.month<<" "<<a.day<<" "<<a.hour<<" "<<a.mini<<' ';
    return out;
}
stringstream & operator>>(stringstream &in,Time & a){
    in>>a.year>>a.month>>a.day>>a.hour>>a.mini;
    return in;
}
bool Time:: operator <(const Time &d)const{
    return year!=d.year?year<d.year:month!=d.month?month<d.month:day!=d.day?hour<d.hour:mini<d.mini;
}
void Time:: print()const
{
      cout<<year<<"年"<<month<<"月"<<day<<"日";
            printf("%02d:%02d
",hour,mini);
}
void Time::set()//容错处理
{
        int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
      cout<<"请依次输入"<<" 年"<<" 月"<<" 日"<<" 小时"<<" 分钟"<<endl;
      cin>>year;
      while(year<2019){cout<<"不是正确时间,请重新输入年"<<endl;cin>>year;}
     cin >>month;
      while(month>12||month<1){cout<<"不是正确时间,请重新输入月"<<endl;cin>>month;}
     cin>>day;
      while(monthdays[judge()][month-1]<day||day<1){cout<<"不是正确时间,请重新输入日"<<endl;cin>>day;}
    cin>>hour;
    while(hour>24||hour<0){cout<<"不是正确时间,请重新输入小时"<<endl;cin>>hour;}
    cin>>mini;
    while(mini>60||mini<0){cout<<"不是正确时间,请重新输入分钟"<<endl;cin>>mini;}
    cout<<"时间已更改为"<<endl;
    print();
}
pair<int,int> Time::tksj(Time &b)//高铁晚上不开车,不考虑超过一天;
{
    pair<int,int>  w;
    if(mini<b.mini)
    {
       w.second=mini-b.mini+60;
       w.first=hour-b.hour-1;
       return w;
    }
    w.second=mini-b.mini;
    w.first=hour-b.hour;
    return w;
}
/*
int main()
{
    Time demo;
    demo.loadtime();
    cout<<demo<<endl;
    demo.print();
}*/
/*int main()
{
    Time demo1;
    cin>>demo1;
    Time demo2(demo1);
    demo1.print();
}*/
/*
int main()
{
    Time demo;
    cout<<demo.judge()<<endl;
    cout<<demo.judge(2008)<<endl;
}*/
/*
int main()
{
    set<Time>demo;
    Time tx;
    int     n=3;
    while(n--)
    {
        tx.set();
        demo.insert(tx);
    }
     set<Time>::iterator po;
    for(po=demo.begin();po!=demo.end();po++)  (*po).print();
}*/
/*
int main()
{
    Time demo1,demo2;
    demo1.loadtime();
    cin>>demo2;
    cout<<demo2.tksj(demo1).first<<' '<<demo2.tksj(demo1).second;
}*/
struct piao
{
    string name;
    int sum[31];
    bool operator <(const piao& a)const
    {
        return name<a.name;
    }
};
class Station
{
    string name; //车站名唯一
    int crotrain;//经过车次数量
    vector<piao> checi; //第一个string是车次,第二个是余票
    //这个车站最多买多少张票,不一定跟总票数相同
public:
    Station(string na,int n);
    Station():name(""),crotrain(0){checi.clear();}
    void print(int riqi);
    void insert(string a);//为站台增加车次
    vector<piao>& quecheci();
    friend istream&   operator>>(istream &in,Station & a);
    friend   ostream&   operator<<(ostream &out,Station & a);
    bool del(string a);
    bool set(string a,int b,int c);// 如果需要调度余票,可以修改
    void setname(string a){this->name=a;}
    string getname(){return name;}
    void buytic(string a,int b);
    void rebac(string a,int b);
};
void Station::rebac(string a,int b)
{
    for(auto po=checi.begin();po!=checi.end();po++)
        if(po->name==a) po->sum[b]++;
}
void Station::buytic(string a,int b)
{
    for(auto po=checi.begin();po!=checi.end();po++)
        if(po->name==a) po->sum[b]--;
}
Station::Station(string na,int n)
{
    name=na;
    crotrain=n;
    for(int i=0;i<n;i++)
    {
       cout<<"输入车次 余票:
";
        piao w;
        cin>>w.name;
        for(int i=0;i<31;i++) cin>>w.sum[i];
      checi.push_back(w);
    }
}
istream& operator>>(istream& in,Station & w)
{
    in>>w.name>>w.crotrain;
    //cout<<w.crotrain<<endl;
    for(int i=0;i<w.crotrain;i++)
    {
        piao qq;
        in>>qq.name;
        for(int i=0;i<31;i++) in>>qq.sum[i];
     w.checi.push_back(qq);
    }
    return in;
}
ostream& operator<<(ostream& out,Station & w)
{
    out<<w.name<<" "<<w.crotrain<<endl;
    for(auto po=w.checi.begin();po!=w.checi.end();po++)
    {
        out<<po->name<<endl;
        for(int i=0;i<31;i++)  out<<po->sum[i]<<' ';
        out<<endl;
    }
    return out;
}
void Station::print(int b)
{
    cout<<name<<":"<<endl;
    for(auto po=checi.begin();po!=checi.end();po++)
    {
        cout<<"车次:"<<po->name<<" 余票:"<<po->sum[b]<<endl;
    }
}
vector<piao>& Station ::quecheci()
{
    return checi;
}
void Station::insert(string a)
{
        piao w;
        w.name=a;
        for(int i=0;i<31;i++) cin>>w.sum[i];
      checi.push_back(w);
}
bool Station::del(string a)
{
    for(auto po=checi.begin();po!=checi.end();po++)
    {
        if(po->name==a) {checi.erase(po);break;}
    }
    if(checi.size()!=crotrain)
    {
        crotrain=checi.size();
        return 1;
    }
    else  return 0;
}
  bool Station::set(string a,int b,int c)
  {
    for(auto po=checi.begin();po!=checi.end();po++)
    {
        if(po->name==a) {
            po->sum[c]=b;
            return 1;
        }
        else return 0;
    }
  }
/*
int main()
{
    int n;
    string a;
    cin>>n>>a;
    Station demo(a,n) ;
    demo.print();
}
*/
/*
int main()
{
    Station demo;
    cin>>demo;
    cout<<demo;
}*/
/*
int main()
{
    Station demo;
    int a;
    string b;
    cin>>b>>a;
    demo.insert(b,a);
    cin>>b>>a;
    demo.insert(b,a);
    vector<pair<string,int>>w=demo.quecheci();
    for(auto po=w.begin();po!=w.end();po++)
        cout<<po->first<<' '<<po->second<<endl;
}*/
/*
int main()
{
    Station demo;
    string a;
    cin>>a;
    demo.setname(a);
    int b;
    cin>>a>>b;
    demo.insert(a,b);
    cin>>a>>b;
    demo.insert(a,b);
    demo.print();
    cin>>a;
    cout<<demo.del(a)<<endl;
    cin>>a;
    cout<<demo.del(a);
    cin>>a>>b;
    cout<<demo.set(a,b)<<endl;
    cin>>a>>b;
    cout<<demo.set(a,b)<<endl;
    demo.print();
}*/
//修改后从新测试,get/set比较比较简单,一般不会写错。
/*
int main()
{
    Station demo;
    string b;
    cin>>b;
    demo.insert(b);
    cin>>b;
    demo.insert(b);
    vector<piao>w=demo.quecheci();
    for(auto po=w.begin();po!=w.end();po++)
       {
            cout<<po->name<<' ';
            for(int i=0;i<31;i++) cout<<po->sum[i]<<' ';
            cout<<endl;
       }

}*/
class Zt  //中规中矩的全家桶数据类
{
    pair<int,int> arrive; //在某站的出发到达时家间;
    pair<int,int> leave;
    string  station;  //作为数据类时指向vector站台;
    int piao[31];// 实际上存在多少票,今天五号,五号前的是下个月,五号后是这个月,不能买今天前的票。
public:
    Zt(string  a,int c,int d,int e,int f):station(a){setarrive(c,d);setleave(e,f);fill(piao,piao+31,100);}
    Zt(){fill(piao,piao+31,100);}
     pair<int,int>  &getarrive(){return arrive;}
     pair<int,int>  &getleave(){return leave;}
    int getarr(); //出发时段到达只是时段
    int getlea();
    string getsta()const{return station;}
    void setarrive(int a,int b){arrive.first=a;arrive.second=b;}  //用于修改出站到站时间;
    void setleave(int a,int b){leave.first=a;leave.second=b;}
    void setsta(string  a){station=a;}
    void printtk();
    void print();
    void printa();
     void printl();
    int getpiao(int i){return piao[i];}
    void setpiao(int a,int b){piao[b]=a;}
    friend istream&operator>>(istream &in,Zt& a);
    friend ostream&operator<<(ostream &out,Zt& a);
};
void Zt:: print()
{
    cout<<station<<endl;
    printf("%02d:%02d ",arrive.first,arrive.second);
    //cout<<arrive.first<<arrive.second<<endl;
    printf("%02d:%02d
",leave.first,leave.second);
   // cout<<leave.first<<leave.second<<endl;
}
void Zt:: printl()
{
    cout<<station<<endl;
    printf("%02d:%02d
",leave.first,leave.second);
}
void Zt:: printa()
{
    cout<<station<<endl;
    printf("%02d:%02d ",arrive.first,arrive.second);
}
int Zt::getarr()
{
    if(arrive.first>=0||arrive.first<6) return 1;
    else if(arrive.first>=6||arrive.first<12) return 2;
    else if(arrive.first>=12||arrive.first<18) return 3;
    else return 4;
}
int Zt::getlea()
{
    if(leave.first>=0||leave.first<6) return 1;
    else if(leave.first>=6||leave.first<12) return 2;
    else if(leave.first>=12||leave.first<18) return 3;
    else return 4;
}
void Zt::printtk()
{
    cout<<leave.second-arrive.second<<"分钟 "<<endl;//没有超过一个小时的;
}
istream&operator>>(istream &in,Zt& a)
{
    in>>a.station;
   // cout<<a.station;
   in>>a.arrive.first;
 //  cout<<a.station;
    in>>a.arrive.second;
//    cout<<a.station;
    in>>a.leave.first;
 //   cout<<a.station;
    in>>a.leave.second;
    //cout<<a.station;
    for(int i=0;i<31;i++) in>>a.piao[i];
    return in;
}
ostream&operator<<(ostream &out,Zt &a)
{
    out<<a.station<<' '<<a.arrive.first<<' '<<a.arrive.second<<' '<<a.leave.first<<' '<<a.leave.second<<' ';
    for(int i=0;i<31;i++) out<<a.piao[i]<<' ';
    out<<endl;
    return out;
}
/*
int main()
{

    string a;
    int b,c,d,e;
     Zt demo(a,b,c,d,e);
    cout<<demo.getpiao(15)<<endl;
}*/
/*
int main()
{
    Zt demo1;
    vector<Zt>demo;
    while(cin>>demo1) demo.push_back(demo1);
    cout<<demo1;
}*/
/*
int main()
{
    short n;
    cin>>n;
    Zt demo(n);
    demo.print();
    demo.printtk();
   cout<<demo.getlea()<<endl;
   cout<<demo.getarr()<<endl;
   cout<<demo.getsta()<<endl;
}
*/
/*
int main()
{
    Zt demo;
   demo.setarrive();
   demo.setleave();
   cout<<demo.getarrive()<<endl;
   cout<<demo.getleave()<<endl;
}
*/
/*
int main()
{
    Zt demo;
    int n;
    cin>>n;
    demo.setpiao(n);
    cout<< demo.getpiao();
}*/
class Train
{
    string train; //车次
    vector<Zt> station;
    vector<string>people;//谁买了票指向peo下标,居题买那张票,再等用户的数据,或者存身份证。
                //双重map,不如直接string
    map<string,int> ys;
    struct node
    {
        int val;
        int len;
        int lazy;
        int l,r;
    }tree[31][300005];
public:

    Train():train(""){people.clear();station.clear();}
    Train(string tr):train (tr){people.clear();station.clear();}
    pair<int,int> buytic(string  a,string  b,int riqi);
    void reback(string  a,string  b,int riqi);
    void insert(string  a,int d,int f,int g,int h,string w);
    bool del(string  a);
    void cx(string a); //查到就打印,查不到就拉倒
    void setarrive(string  a);//修改某个站的到站时间出发时间
    void setleave(string a);
    void setsta(string a);
    int cxyp(string a, string b,int c);
    vector<string>&getpeople(){return people;}
   // void printf();无法获取站台信息,只能传引用了
     vector<Zt>& getzt(){return station;}
     friend istream&operator>>(istream& in,Train &a);
     friend ostream&operator<<(ostream& out,Train &a);
     void settr(string a){train=a;}
     string  gettr(){return train;}
     //void built_tree( int node, int left, int right,int day );
  //  void  pushdown(int root,int day)  ;//向下传递lazy标记
  //  int query(int root,int l,int r,int day);  //计算区间和
  //  void  update(int root,int l,int r,int addval,int day);  //区间更新
};
/*void Train:: built_tree(int root,int l,int r,int day)  //建树
{
    int mid;
    tree[day][root].lazy=0;
    tree[day][root].l=l;
    tree[day][root].r=r;
    tree[day][root].len=r-l+1;
    if (l==r) tree[day][root].val=station[l].getpiao(day);
    else
    {
        mid=(l+r)/2;
        built_tree(root*2,l,mid,day);
        built_tree(root*2+1,mid+1,r,day);
        tree[day][root].val=min(tree[day][root*2].val,tree[day][root*2+1].val);
    }
}*/
/*void Train:: pushdown(int root,int day)  //向下传递lazy标记
{
    if (tree[day][root].lazy)
    {
        tree[day][root*2].lazy+=tree[day][root].lazy;
        tree[day][root*2+1].lazy+=tree[day][root].lazy;
        tree[day][root*2].val+=tree[day][root].lazy;
        tree[day][root*2+1].val+=tree[day][root].lazy;
        tree[day][root].lazy=0;
    }
}
int Train:: query(int root,int l,int r,int day)  //计算区间和
{
    int mid;
    if (tree[day][root].l>=l&&tree[day][root].r<=r)
        return tree[day][root].val;
    if (tree[day][root].l>r||tree[day][root].r<l)
        return 0x7f7f7f7f;
    if (tree[day][root].lazy) pushdown(root,day);
    return min(query(root*2,l,r,day),query(root*2+1,l,r,day));
}
void Train:: update(int root,int l,int r,int addval,int day)  //区间更新
{
    int mid;
    if (tree[day][root].l>=l&&tree[day][root].r<=r)
    {
        tree[day][root].lazy+=addval;
        tree[day][root].val+=addval;
        return;
    }
    if (tree[day][root].l>r||tree[day][root].r<l)
        return;
    if (tree[day][root].lazy) pushdown(root,day);
    update(root*2,l,r,addval,day);
    update(root*2+1,l,r,addval,day);
    tree[day][root].val=min(tree[day][root*2].val,tree[day][root*2+1].val);
}*/
pair<int,int>  Train::buytic(string  a,string  b,int c)  //站台的票和列车票是分步的 ,这是买票操作的一部分。
{
    pair<int,int> www;
 //   update(1,ys[a],ys[b],-1,c);
    www=station[ys[a]].getleave();
    return www;
}
void  Train::reback(string  a,string  b,int riqi)
{
   //update(1,ys[a],ys[b],1,riqi);
}
void Train::insert(string  a,int d,int f,int g,int h,string w)
{
   Zt tem(a,d,f,g,h);
   if(w=="END"||w=="end"||w=="End")
   {
       station.push_back(tem);
       ys.insert(make_pair(a,station.size()-1));
   }
   else {
        station.insert(station.begin()+ys[w],tem);
        for(auto po=station.begin()+ys[w]-1;po!=station.end();po++)
        {
            ys.insert(make_pair(po->getsta(),po-station.begin()));
        }
   }
//    for(int i=0;i<=31;i++)built_tree(0,0,station.size()-1,i);
}
int  Train::cxyp(string  a,string  b,int c)
{
   //  return  query(1,ys[a],ys[b],c);
}
/*
void Train::print()
{
    for(auto po=station.begin();po!=station.end();po++)
    {
        cout<<
    }
}*/
bool  Train::del(string  a)
{
    bool flag=0;
    for(auto po=station.begin();po!=station.end();po++)
    {
        if(po->getsta()==a)
        {
            station.erase(po);
            flag=1;
            break;
        }
    }
    return flag;
}
void  Train::cx(string  a)
{
    for(auto po=station.begin();po!=station.end();po++)
    {
        if(po->getsta()==a)
        {
            po->print();
            po->printtk();
            break;
        }
    }
}
void Train::setarrive(string   a)
{
    for(auto po=station.begin();po!=station.end();po++)
    {
        if(po->getsta()==a)
        {
            int a,b;
            cin>>a>>b;
            po->setarrive(a,b);
            break;
        }
    }
}
void Train:: setleave(string  a)
{
    for(auto po=station.begin();po!=station.end();po++)
    {
        if(po->getsta()==a)
        {
            int a,b;
            cin>>a>>b;
            po->setleave(a,b);
            break;
        }
    }
}
void  Train::setsta(string  a)
{
    for(auto po=station.begin();po!=station.end();po++)
    {
        if(po->getsta()==a)
        {
            po->setsta(a);
            break;
        }
    }
}
istream&operator>>(istream& in,Train &a)
{
    //vector<Zt> ww;
    a.ys.clear();
    int m,n;
            Zt demo;
    in>>a.train>>n>>m;//=0;
    while(n--)
    {
        in>>demo;
        a.station.push_back(demo);
        a.ys.insert(make_pair(demo.getsta(),a.station.size()-1));
      //  cout<<ww.station.size()<<endl;
    }
   // a.station.swap(ww);
    while(m--)
    {
        string w;
        in>>w;
       a. people .push_back(w);
    }
//    for(int i=0;i<=31;i++)a.built_tree(0,0,a.station.size()-1,i);
    return in;
}
ostream&operator<<(ostream& out,Train &a)
{
    out<<a.train<<' '<<a.station.size()<<' '<<a.people.size()<<endl;
    for(auto po=a.station.begin();po!=a.station.end();po++) out<<*po<<' ';
    for(auto po=a.people.begin();po!=a.people.end();po++) out<<*po<<' ';
    out<<endl;
    return out;
}
/*
int main()
{
    Train demo;
    cin>>demo;
    cout<<demo;
}*/
/*
int main()
{
    Train demo;
    short a,b;
    int c;
    cin>>a>>c;
    demo.insert(a,c);
    cin>>b>>c;
    demo.insert(b,c);
    cout<<demo.cxyp(a,b)<<endl;
    demo.buytic(a,b);
    cout<<demo.cxyp(a,b)<<endl;
    demo.reback(a,b);
    cout<<demo.cxyp(a,b)<<endl;
}
*/
/*
int main()
{
    Train demo;
    cin>>demo;
    short int a;
    cin>>a;
    demo.cx(a);
    demo.del(a);
    demo.cx(a);
    cin>>a;
    demo.setarrive(a);
        demo.cx(a);
    demo.setleave(a);
        demo.cx(a);
    demo.setsta(a);
        demo.cx(a);
}*/
/*
int main()
{
    Train demo;
    cin>>demo;
    cout<<demo.gettr()<<endl;
    string tem;
    cin>>tem;
    demo.settr(tem);
    cout<<demo.gettr()<<endl;
}*/

int main()
{
    Train demo;
    cin>>demo;
    string a,b;
    int c;
   int d,e,f,g;
  cin>>a>>d>>e>>f>>g>>b;
  demo.insert(a,d,e,f,g,b);
    cin>>a>>b>>c;
    cout<<demo.cxyp(a,b,c)<<endl;
    cin>>a>>b>>c;
     cout<<demo.cxyp(a,b,c)<<endl;
    demo.buytic(a,b,c);
     cout<<demo.cxyp(a,b,c)<<endl;
     demo.reback(a,b,c);
      cout<<demo.cxyp(a,b,c)<<endl;
}
class Tick //即使车票,又是记录
{
    Time buy;
    Time leave; //出发时间,用于确定存日志文件
    string  from;
    string  to;
    string id;
    string name;
public:
    //只有get函数
    Tick():from(" "),to(" "),id(" "){}
    Tick(Time b,Time l,string f,string t,string i,string w):buy(b),leave(l),from(f),to(t),id(i),name(w){}
    Time&getbuy(){return buy;}
    Time&getlea(){return leave;}
    string getfrom(){return from;}
    string getto(){return to;}
    string getid(){return id;}
    string getname();//本来想hash,但是有点复杂
   void print();
   string getna(){return name;}
    bool operator ==(Tick &a);
    friend istream& operator>>(istream& in,Tick &a );
    friend ostream& operator<<(ostream &out,Tick &a );
};
string Tick::getname()
{
    string w;
    stringstream tem;
    w.clear();
    tem.clear();
    tem<<leave.getday();
    tem<<leave.getmonth();
    tem<<leave.getyear();
    tem>>w;
    w=w+id+from+to;
    return w;
}
bool Tick::operator ==(Tick &a)
{
   return a.buy==buy?(a.leave==leave?(from==a.from?(to==a.to?id==a.id:0):0):0):0;
}
istream& operator>>(istream &in,Tick &a )
{
    in>>a.buy>>a.leave>>a.from>>a.to>>a.id>>a.name;
    return in;
}
ostream& operator<<(ostream &out,Tick &a )
{
    out<<a.buy<<' '<<a.leave<<' '<<a.from<<' '<<a.to<<' '<<a.id<<' '<<a.name<<endl;
    return out;
}
void Tick::print()
{
    cout<<leave<<endl;
    cout<<from<<"----->"<<to<<endl;
    cout<<id<<endl;
}/*
int main()
{
    Tick demo;
    cin>>demo;
    cout<<demo.getname()<<endl;
}*/
/*
int main()
{
    Tick demo;
    cin>>demo;
    cout<<demo;
}
*/
/*
int main()
{
    Time demo1,demo2;
    short a,b;
    string  id;
    cin>>demo1>>demo2>>a>>b>>id;
    Tick demo(demo1,demo2,a,b,id);
    cout<<demo.getbuy()<<endl;
    cout<<demo.getlea()<<endl;
    cout<<demo.getfrom()<<endl;
    cout<<demo.getto()<<endl;
    cout<<demo.getid()<<endl;
}*/
/*
int main()
{
    string a,b,c;
    cin>>a>>b>>c;
    Time q, e;
    cin>>q>>e;
    Tick demo(q,e,a,b,c);
    cout<<demo;
    demo.print();
}*/
/*
int main()
{
    Tick demo;
    cin>>demo;
    demo.print();
}*/
class User//用户信息
{
    string name;
    string id;  //不能改
    vector<string > tic;
    string phone;
    string key;
    bool ban;//黑名单
public:
    User():name(""),id(""),phone(""){tic.clear();}
    User(string a,string b,string c):name(a),id(b),phone(c){tic.clear();}
    void buytic(string  a){   tic.push_back(a);} //只考虑买就行了,判断能不能买在下面的类.
    void setph(string p){    phone=p;}
    vector<string >& gettic(){return tic;}
    string getname(){return name;}
    string getphone(){return phone;}
    string getid(){return id;}
    string getkey(){return key;}
    void del(string  a);  //这是系统操作出行后,就看不到订单了。
    int getboupiao(){return tic.size();}
    bool getban(){return ban;}
    friend istream&operator>>(istream&in,User&a);
    friend ostream&operator<<(ostream&out,User&a);
};
void User::del(string  a)
{
   for(auto po=tic.begin();po!=tic.end();po++)
   {
       if(*po==a) tic.erase(po);
   }
}
istream&operator>>(istream&in,User&a)
{
    int w;
    in>>a.name>>a.id>>a.phone>>a.key>>a.ban>>w;
    while(w--)  //一个月前的就不读了
    {
        string  q;
        in>>q;
        int dday=(q[0]-'0')*10+(q[1]-'0');
        int dmonth=(q[2]-'0')*10+(q[3]-'0');
        int dyear=(((q[4]-'0')*10+(q[5]-'0'))*10+(q[6]-'0'))*10+(q[7]-'0');
        Time tem(dyear,dmonth,dday);
        Time now;
        now.loadtime();
        if(now>tem) continue;
        a.tic.push_back(q);
    }
    return in;
}
ostream&operator<<(ostream&out,User&a)
{
    out<<a.name<<' '<<a.id<<' '<<a.phone<<' '<<a.key<<' '<<' '<<a.ban<<' '<<a.tic.size()<<endl;
    for(auto po=a.tic.begin();po!=a.tic.end();po++) out<<*po<<' ';
    return out;
}
/*
int main()
{
    User demo;
    cin>>demo;
    cout<<demo;
}
*/
/*
int main()
{
    string name,id,phone;
    cin>>name>>id>>phone;
    User demo(name,id,phone);
    cout<<demo.getname()<<endl;
    cout<<demo.getid()<<endl;
    cout<<demo.getphone()<<endl;
    cin>>phone;
    demo.setph(phone);
    cout<<demo.getphone()<<endl;
}
*/
/*
int main()
{
    User demo;
    int a;
    cin>>a;
    demo.buytic(a);
    cin>>a;
    demo.buytic(a);
    vector<int>   w=demo.gettic();
    for(auto po=w.begin();po!=w.end();po++)cout<<*po<<endl;
    cin>>a;
    demo.del(a);
    w=demo.gettic();
    for(auto po=w.begin();po!=w.end();po++)cout<<*po<<endl;
}*/
class Baseque //查询类
{
protected:
    //12306所有的都具有唯一性。
    vector<Station> station;//列车里的int(站台编号)对应station的int;
    map<string,int>natosta;
    vector<Train> train;
    map<string,int>checitotrain;
   // vector<User> user;
  //  map<string,int> idtouser;
  //  vector<Tick> tick;
//    map<int,int> nutotic;
public:
    Baseque(){station.clear();natosta.clear();train.clear();checitotrain.clear();load();}
    void czcc(string a,int b,int d);
    void  cxcx(string a);
    bool cxyp(string a,string b,int c);
    void load();
    void save();
   //void insert()
    ~Baseque(){save();}
};
    /*void Baseque;;insert()
    {
        Train  tem2;
        while(    cin>>tem2)
            {
                 cout<<-2;  //手动调试点

         if(tem2.gettr()=="$$") continue;
         train.push_back(tem2);
         checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));

            }
    }*/
void Baseque ::czcc(string a,int b,int d)
{
    vector<piao>w=station[natosta[a]].quecheci();
    for(auto po=w.begin();po!=w.end();po++)
    {
       vector<Zt> q= train[checitotrain[po->name]].getzt();
       for(auto pi=q.begin();pi!=q.end();pi++)
       {
            if(a==pi->getsta())
             {
                 if(pi->getarr()==b||b==0||pi->getlea()==d||d==0)
                 {
                      cout<<po->name<<endl;
                     if(pi!=q.begin())
                     {
                            q.begin()->printl();

                           // cout<<1<<endl;
                            if(pi==q.end()-1)
                            {
                                (q.end()-1)->printa();
                               //cout<<2<<endl;
                                    cout<<endl;
                            }
                            else
                            {
                                pi->print();
                                  //   cout<<endl;
                                (q.end()-1)->printa();
                               //  cout<<3<<endl;
                            }
                             cout<<endl;
                     }
                     else
                     {
                                q.begin()->printl();
                                (q.end()-1)->printa();
                                cout<<endl;
                     }
                     cout<<endl;
                 }
             }
           //  pi->print();

       }
      //  cout<<endl;
    }
}
void Baseque ::cxcx(string a)  //车次查询
{
    if(checitotrain.find(a)==checitotrain.end())
    {
        cout<<"NO Train"<<endl;
        return ;
    } //查不到不打印
    vector<Zt> w=train[checitotrain[a]].getzt();
    for(auto po=w.begin();po!=w.end();po++)
    {
        cout<<station[natosta[po->getsta()]].getname()<<' ';
        if(po!=w.begin()&&po!=w.end()-1)
        {
            po->print();
           //cout<< po->getleave().first<<' '<<po->getleave().first;
        }
          else if(po==w.begin())
          {
               cout<< po->getleave().first<<' '<<po->getleave().first;
          }
          else   cout<<po->getarrive().first<<' '<< po->getarrive().second<<' ';
    }
    cout<<endl;
}
bool Baseque :: cxyp(string a,string b,int riqi)
{
    auto w=station[natosta[a]].quecheci();
    auto v=station[natosta[b]].quecheci(); //vector<pair<string,int>> checi
    set<piao>tem;
    vector<piao>temp;
    temp.clear();
    for(auto po=w.begin();po!=w.end();po++) tem.insert(*po);
    for(auto po=v.begin();po!=v.end();po++)
    {
        if(tem.insert(*po).second==0) temp.push_back(*po);
    }
    if(temp.size()==0)
    {
        cout<<"No ticket"<<endl;
        return 0 ;
    }
    for(auto po=temp.begin();po!=temp.end();po++)
    {
       auto x= train[checitotrain[po->name]].getzt();
       int mini=po->sum[riqi];
       int ss=train[checitotrain[po->name]].cxyp(a,b,riqi);
       mini=min(mini,ss);
       cout<<train[checitotrain[po->name]].gettr()<<endl;;
       for(auto pi=x.begin();pi!=x.end();pi++) //336
       {
            //cout<<s
            pi->print();
       }
       cout<<mini<<endl;
    }
    return 1;
}
void Baseque::load()
 {
     int x,y,n;
    ifstream in1("station.txt",ios::in);
    in1>>n;
     while(    n--)
     {
              Station tem1;
          in1>>tem1;
            //      cout<<-1; 手动调试点
         if(tem1.getname()=="$$") continue;
         station.push_back(tem1);
         natosta.insert(make_pair(tem1.getname(),station.size()-1));
     //    cout<<1;

     }
     in1.close();
     ifstream in2("train.txt",ios::in);

     in2>>n;
       while(n--   )
    {
             Train tem2;
         in2>>tem2;
                // cout<<-2;  //手动调试点

         if(tem2.gettr()=="$$") continue;
         train.push_back(tem2);
         checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));
    }
    in2.close();
}
void Baseque::save()
 {
  ofstream out1("station.txt",ios::out);
  out1<<station.size()<<endl;
     for(auto po=station.begin();po!=station.end();po++)
        out1<<*po<<endl;
    out1.close();
    ofstream out2("train.txt",ios::out);
    out2<<train.size()<<endl;
     for(auto po=train.begin();po!=train.end();po++)
        out2<<*po<<endl;
        out2.close();
 }
 /*
int main()
{
    Baseque demo;
    cin>>demo;
    cout<<demo;
}
*/
/*
int main()
{
    Baseque demo;
    string a;
    int c;
    int b;
    cin>>a>>b>>c;
    demo.czcc(a,b,c);
    cin>>a>>b>>c; //一天分四个时段查询。5就查不到
    demo.czcc(a,b,c);
}*/
/*
int main()
{
    Baseque demo;
    string a;
    int c;
    int b;
    cin>>a;//>>b>>c;
    demo.cxcx(a);
    cin>>a;//>>b>>c;
    demo.cxcx(a);
}
*/
/*
int main()
{
    Baseque demo;
    string a,b;
    cin>>a>>b;
    demo.cxyp(a,b);
}
*/
/*
int main()
{
    Baseque demo;
}*/
class Client:public Baseque
{
protected:
    vector<User> user;
    map<string,int> idtouse;
    vector<Tick>tick;
    map<string,int> hashtotick;
    int now;//用于记录当前用户
    string now2;
public:
        Client(){load2();}
    void load2();
    void save2();
    bool buytic(string a,string b,int c);
    void reback();
    void replacetic();
    virtual void login();
    void setphone(string a);
    void printmp();
    ~Client(){save2();}
};
 void Client::printmp()
 {
    auto ww=user[now].gettic();
    for(auto po=ww.begin();po!=ww.end();po++)
    {
        cout<<po-ww.begin()+1<<endl;
       tick[ hashtotick[*po]].print();
    }
 }
bool Client::buytic(string a,string b,int c) //先查后买,查不到不能买。
{
    if(!(cxyp(a,b,c))){cout<<"无票"<<endl;return 0;}
    if(user[now].getboupiao()>5||user[now].getban())
    {
        cout<<"购票限制"<<endl;
        return 0;
    }
   else
    {
        string id;
        cin>>id;
        pair<int,int>www=train[checitotrain[id]].buytic(a,b,c);
        station[natosta[a]].buytic(a,c);
        Time no1,no2;
        no1.loadtime();
        no2.loadtime();
        no2.seth(www.first,www.second);
        if(no2.getday()<c) no2.setmonth(no2.getmonth()+1);
        Tick tem(no1,no2,a,b,now2,id);
        tick.push_back(tem);
        hashtotick.insert(make_pair(tem.getname(),tick.size()-1));
        user[now].buytic(tem.getname());
    }
    return 1;
}
void Client::reback() //先查后买,查不到不能买。
{
        printmp();
        string id=now2;
        int n;
        cout<<"退哪一张票"<<endl;
        cin>>n;
        n=n-1;
    auto ww=user[now].gettic();
 string a=tick[ hashtotick[ww[n]]].getfrom();
         cout<<1<<endl;;
      string b=tick[ hashtotick[ww[n]]].getto();
         cout<<2<<endl;;
       int c=tick[ hashtotick[ww[n]]].getlea().getday();
         cout<<3<<endl;;
        train[checitotrain[id]].reback(a,b,c);
        cout<<4<<endl;;
         string e=tick[ hashtotick[ww[n]]].getna();
       station[natosta[a]].rebac(e,c);
        cout<<5<<endl;;
     // tick.erase(hashtotick[ww[n]]+tick.begin());

}
void Client::replacetic()
{
    string a,b,id;
    int c;
    cin>>a>>b>>c;
  if(  buytic(a,b,c))
   {
        cin>>a>>b>>c;
        reback();
   }
}
void Client::setphone(string a)
{
    user[now].setph(a);
}
void Client::login()
{
    string phone;
    string key;
    while(cin>>phone>>key)
    {
           for(auto po=user.begin();po!=user.end();po++)
           {
               if(po->getphone()==phone)
                   if(po->getkey()==key)
                    {
                        cout<<"Login prosperity"<<endl;
                        now=po-user.begin();
                        now2=po->getid();
                        return ;
                    }
           }
           cout<<"Wrong password"<<endl;
    }
}
void Client::load2()
{
    ifstream in("user.txt",ios::in);
    int n;
    if(!in) return ;
    in>>n;
    while(n--)
    {
        User tem;
        in>>tem;
        user.push_back(tem);
        idtouse.insert(make_pair(tem.getname(),user.size()-1));
    }
    in.close();
    ifstream in2("tick.txt",ios::in);
    if(!in2) return ;
    in2>>n;
    while(n--)
    {
        Tick tem;
        in2>>tem;
        if(tem.getname()=="$$$") continue;
        tick.push_back(tem);
        hashtotick.insert(make_pair(tem.getname(),tick.size()-1));
    }
    in.close();
}
void Client::save2()
{
    ofstream out("user.txt",ios::out);
    out<<user.size()<<endl;
    for(auto po=user.begin();po!=user.end();po++) out<<*po<<endl;
    out.close();
    ofstream out2("tick.txt",ios::out);
    stringstream sss;
    Time now;
    now.loadtime();
    string temp;
    sss<<now.getyear()<<"年"<<now.getmonth()<<"月"<<now.getday()<<"日";
    sss>>temp;
    ofstream out3(temp,ios::out);   //做过的车,就存到日志文件不在读取。
    int sum=0;
    for(auto po=tick.begin();po!=tick.end();po++)
    {
        if(now>po->getlea())
        {
            out3<<*po<<endl;
        }
        else sum++;
    }
    out3.close();
    out2<<sum<<endl;
    for(auto po=tick.begin();po!=tick.end();po++)
    {
        if(now>po->getlea()) continue;
        out2<<*po<<endl;
    }
    out2.close();
}
/*
int main()
{
    Client demo;
    //demo.login();
}*/

/*int main()
{
    Client demo;
    demo.login();//登陆密码18053176044 123456
    string a,b;
    int riqi;
    cin>>a>>b>>riqi;
    demo.buytic(a,b,riqi);
    demo.cxyp(a,b,riqi);
}*/
/*
int main()
{
    Client demo;
    demo.login();
    string a,b;
    int riqi;
    cin>>a>>b>>riqi;
    demo.buytic(a,b,riqi);
    demo.reback();
    demo.cxyp(a,b,riqi);
}*/
class Admin:public Client
{
public:
    void login(){}
    void insertsta();
    bool delsta(string a);
    void setsta(string a);
    void inserttr();
    bool deltr(string a);
    void settr(string a);
};
void Admin:: insertsta()
{
    Station tem1;
    cin>>tem1;
    station.push_back(tem1);
    natosta.insert(make_pair(tem1.getname(),station.size()-1));
}
bool Admin::delsta(string a)
{
    for(auto po=station.begin();po!=station.end();po++)
    if(po->getname()==a)
    {
        vector<piao> ww=po->quecheci();
        for(auto pi=ww.begin();pi!=ww.end();pi++)
            train[checitotrain[pi->name]].del(a);
        station.erase(po);
        return 1;
    }
    cout<<"无此车站"<<endl;
    return 0;
}
void Admin::setsta(string a)
{
    if(!delsta(a))return ;
    insertsta();
    return ;
}
void Admin::inserttr()
{
    Train tem2;
    cin>>tem2;
    train.push_back(tem2);
    checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));
    return ;
}
bool Admin::deltr(string a)
{
    for(auto po=train.begin();po!=train.end();po++)
    if(po->gettr()==a)
    {
        vector<Zt> ww=po->getzt();
        for(auto pi=ww.begin();pi!=ww.end();pi++)
            station[natosta[pi->getsta()]].del(a);
        train.erase(po);
                return 1;
    }
    cout<<"无此高铁"<<endl;
    return 0;
}
void Admin::settr(string a)
{
    if(!deltr(a))return ;
    inserttr();
}
/*
int main()
{
    Admin demo;
    demo.insertsta();
    string a;
    cin>>a;
    demo.delsta(a);
  //  cout<<1<<endl;
    demo.insertsta();
    cin>>a;
    demo.setsta(a);
   // cout<<2<<endl;
}*/
/*
int main()
{
    Admin demo;
    demo.inserttr();
}*/
/*
int main()
{
    Admin demo;
    demo.inserttr();
     string a;
    cin>>a;
    demo.deltr(a);
}*/
/*
int main()
{
    Admin demo;
    demo.inserttr();
    string a;
    cin>>a;
    demo.settr(a);
 //   cout<<2<<endl;
}
*/
原文地址:https://www.cnblogs.com/lunatic-talent/p/12798330.html