-
Notifications
You must be signed in to change notification settings - Fork 0
/
SubwaySystem.cpp
205 lines (187 loc) · 5.16 KB
/
SubwaySystem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "SubwaySystem.h"
int SHORT=66666;
bool flag=false;
SubwaySystem::SubwaySystem(string filename){//从文件读入地铁信息
Handle_File(filename.c_str());
};
void SubwaySystem::Line_Inquiry(){
cout << endl;
string line;
cout << "Line:" << endl;
cin >> line;
if (routes.find(line) != routes.end())
{
cout << "Stations of ";
print_line(line);
cout << " :" << endl;
for (int i = 0; i < routes[line].size(); ++i){
cout << routes[line][i];
if(i!=routes[line].size()-1)
cout << " - ";
}
cout << endl;
}
}
void SubwaySystem::Site_Inquiry(){
cout << endl;
string site;
getline(cin, site);
cout << "Site:" << endl;
getline(cin, site);
if (lines.find(site) != lines.end()){
cout << "Line Information:" << endl;//打印所属线路
for(const auto&a:lines[site]){
print_line(a);
cout << endl;
}
cout << "Adjacent station(s):" << endl;//打印相邻站点名称
for(const auto&a:adj_table[site])
cout << a << endl;
}
}
void SubwaySystem::Route_Inquiry(){
string start, destination;
getline(cin, start);
cout<<"Departure Station:"<<endl;
getline(cin, start);
cout<<"Destination:"<<endl;
getline(cin, destination);
Find_Route(start, destination);
}
void SubwaySystem::Handle_File(const char* filename)
{
//从文件读入地铁信息
ifstream infi(filename, ios::in);
string line;
//读入线路名
while(getline(infi,line)){
string temp;
if ((line.size() <= 2 && isdigit(line[0])) || line == "3_1" || line == "APM" || line == "GF"|| line == "14_1")
{
//先输入和处理线路
Station prev,curr;
vector<string> route;
while(getline(infi,temp)){//输入和处理站点
if(temp.size()==0)
break;
curr.set(temp);
stations[temp]=curr;
lines[temp].insert(line);
route.push_back(temp);
if(prev.name!=""){
adj_table[temp].push_back(prev.name);//图记录:上一站的站点名称、线路名称
adj_table[prev.name].push_back(temp);
}
prev = curr;
}
if(!route.empty())
routes[line] = route;
}
}
}
void SubwaySystem::BFS_Dispose(map<string,bool> &vis_table,const string& start,const string& destination)
{
queue<string> wait;
wait.push(start);//将起始站推入队列
vis_table[start]=true;
string curr;
//广搜
while(!wait.empty())
{
curr = wait.front();
if (curr == destination)//若搜到目标站点
{
//将经过的站点存储到最短路径的容器中
string mark = curr;
while(mark!=start){
theShortestPath.push_front(mark);
mark = stations[mark].prev;
}
theShortestPath.push_front(start);//存入起始站
return;
}
sort_by_lines(adj_table[curr]);//根据可换乘车站的数目进行排序,先访问可换乘车站的数目少的站点,从而使最短路径的是所有等长路径中换乘次数最少的
for (auto a:adj_table[curr])
{
if(!vis_table[a]){
stations[a].setPrev(curr);
wait.push(a);
vis_table[a] = true;
}
}
wait.pop();
}
}
string SubwaySystem::get_line(const string &a, const string &b){
//找到并返回两个车站都属于的线路
for(const auto &e:lines[a]){
if(lines[b].count(e))
return e;
}
return "";
}
void SubwaySystem::print_line(const string &line){
if(line=="3_1")//3号线北延段
cout << "North extension of Line 3";
else if(line=="14_1")//14号线支线
cout << "Extension of Line 14";
else
cout << "Line " << line;
}
void SubwaySystem::sort_by_lines(vector<string> &v){
for (int i = v.size() - 1; i > 0; i--)
{
for (int j = 1; j <= i;j++){
if(lines[v[j]].size()<lines[v[j-1]].size()){
string temp = v[j - 1];
v[j - 1] = v[j];
v[j] = temp;
}
}
}
}
void SubwaySystem::Print_ShortestPath(){
if(theShortestPath.size()<2)
return;
auto curr = theShortestPath.begin(), next = curr;
++next;//记录下一个车站
string line = get_line(*curr, *next);
print_line(line);
cout << ": ";
while(next!=theShortestPath.end()){
if(get_line(*curr,*next)!=line){//该站和下一个站都属于的线路和当前线路不同说明需要换乘
line = get_line(*curr, *next);
cout << *curr;
cout << "(Tranfer to ";
print_line(line);
cout << ")" << endl;
print_line(line);
cout << ": ";
}
else
cout << *curr << " ---> ";
curr = next;
next++;
}
//打印终点站
cout << *curr << endl;
cout << "A total of " << theShortestPath.size() - 1 << " stations." << endl;
}
void SubwaySystem::Find_Route(string& start,string& destination)
{
if(stations.find(start)!=stations.end()&&stations.find(destination)!=stations.end()&&start!=destination){
map<string, bool> vis_table;
for(auto a:stations)
vis_table[a.first] = false;
BFS_Dispose(vis_table,start,destination);
cout << endl;
cout << "The shortest path:" << endl;
Print_ShortestPath();
}
else if(stations.find(start)==stations.end())
cout << "Missing departure station." << endl;
else if(stations.find(destination)==stations.end())
cout << "Missing destination." << endl;
else
cout << "The departure station is the same as the destination."<<endl;
}