设计一个火车票查询系统, 已知国内所有的火车列次信息,每列火车所经过的站点,各站点之间的里程、价格等信息。要求设计一个数据结构或算法(可自定义数据结构或使用数据库),完成如下需求: 1、根据列车车次号查询该次列车经过的所有站点。(例如查询 T1 次列车经过的所有站点结果为:北京、石家庄、郑州、武汉、长沙) 2、根据某一个站点名称,查询所有经过该站点的列车。(例如查询所有经过北京的列车车次) 3、给出任意两个站点作为出发和终点站,查询可乘车次(例如查询北京去长沙可乘的所有列车车次) 4、附加题: 考虑中转问题, 从某个站点可能需要中间转车才可到达,例如从哈尔滨到重庆,需要在北京或其他站点转车才可到达。 设计要求: 1、以用户体验为中心 2、考虑设计性能 3、如使用数据库则需要写明具体的表结构和 SOL语句,如自行设计存储和算法请详细描述设计思路和算法流程。
时间: 2024-03-20 16:40:04 浏览: 60
placro:一个交互式站点,可帮助人们根据自己的宏计划膳食。 里程碑项目2-CI
为了实现以上需求,可以设计一个基于数据库的火车票查询系统。具体的设计思路如下:
1. 数据库设计
首先需要设计数据库的表结构,包括列车信息表、站点信息表、列车-站点关系表等。具体的表结构和相关SQL语句如下:
- 列车信息表(train_info)
| 列名 | 数据类型 | 说明 |
| --------- | ----------- | -------------- |
| train_no | varchar(10) | 列车车次号 |
| start_sta | varchar(50) | 始发站 |
| end_sta | varchar(50) | 终到站 |
| start_time| datetime | 始发时间 |
| end_time | datetime | 到达时间 |
| duration | int | 行驶时间(分钟)|
- 站点信息表(station_info)
| 列名 | 数据类型 | 说明 |
| -------- | ----------- | ------------ |
| station | varchar(50) | 站点名称 |
| mileage | int | 里程(公里) |
- 列车-站点关系表(train_station)
| 列名 | 数据类型 | 说明 |
| --------- | ----------- | -------------- |
| train_no | varchar(10) | 列车车次号 |
| station | varchar(50) | 站点名称 |
| order_no | int | 站点在列车中的顺序 |
| start_time| datetime | 到达时间 |
| end_time | datetime | 离开时间 |
| price | float | 该站点的票价 |
2. 系统功能实现
根据以上需求,实现以下功能:
- 根据列车车次号查询该次列车经过的所有站点
```sql
SELECT station FROM train_station WHERE train_no = 'T1' ORDER BY order_no;
```
- 根据某一个站点名称,查询所有经过该站点的列车
```sql
SELECT train_no FROM train_station WHERE station = '北京' OR station = '石家庄' OR station = '郑州' OR station = '武汉' OR station = '长沙' GROUP BY train_no;
```
- 给出任意两个站点作为出发和终点站,查询可乘车次
```sql
SELECT t1.train_no FROM train_station t1 JOIN train_station t2 ON t1.train_no = t2.train_no AND t1.station = '北京' AND t2.station = '长沙' AND t1.order_no < t2.order_no;
```
- 中转问题的解决
对于中转问题,可以通过以下算法实现:
1. 从始发站开始,按照时间顺序逐个查找所有可到达的站点,记录下到达该站点所需的最短时间。
2. 根据所有到达该站点所需的最短时间,计算出从始发站到该站点的最短时间。
3. 以该站点为起点,重复以上步骤,查找到达终点站所需的最短时间,并计算出从始发站到终点站的最短时间。
4. 查询所有行程中经过该站点的列车车次,并计算出所需的总时间。
具体的算法流程如下:
```python
# 从始发站开始,按照时间顺序逐个查找所有可到达的站点,记录下到达该站点所需的最短时间。
def find_shortest_time(start_sta, end_sta):
# 初始化起点的最短时间为0,其他站点的最短时间为无穷大
shortest_time = {start_sta: 0}
for station in station_list:
if station != start_sta:
shortest_time[station] = float('inf')
# 按照时间顺序查找所有站点
for t in range(0, 24 * 60, 5):
for train in train_list:
if start_sta in train and train.index(start_sta) < len(train) - 1:
# 找到从起点出发的列车
cur_sta = start_sta
cur_time = t
for i in range(train.index(start_sta) + 1, len(train)):
# 查找到达该站点的时间
next_sta = train[i]
next_time = cur_time + get_travel_time(cur_sta, next_sta, cur_time)
if next_time < shortest_time[next_sta]:
shortest_time[next_sta] = next_time
# 如果已经到达终点站,则退出循环
if next_sta == end_sta:
break
cur_sta = next_sta
cur_time = next_time
return shortest_time
# 计算从始发站到终点站的最短时间
def find_total_time(start_sta, end_sta):
shortest_time1 = find_shortest_time(start_sta, end_sta)
shortest_time2 = find_shortest_time(end_sta, start_sta)
total_time = float('inf')
for station in station_list:
if station in shortest_time1 and station in shortest_time2:
time = shortest_time1[station] + shortest_time2[station]
if time < total_time:
total_time = time
return total_time
# 查询所有行程中经过该站点的列车车次
def find_trains(start_sta, end_sta):
trains = []
for train in train_list:
if start_sta in train and end_sta in train and train.index(start_sta) < train.index(end_sta):
trains.append(train)
return trains
# 计算从始发站到终点站经过该站点的总时间
def find_total_time_with_transfer(start_sta, transfer_sta, end_sta):
time1 = find_total_time(start_sta, transfer_sta)
time2 = find_total_time(transfer_sta, end_sta)
trains1 = find_trains(start_sta, transfer_sta)
trains2 = find_trains(transfer_sta, end_sta)
total_time = float('inf')
for train1 in trains1:
for train2 in trains2:
if train1[-1] == transfer_sta and train2[0] == transfer_sta:
time = time1 + time2 + get_transfer_time(train1[-1], train2[0])
if time < total_time:
total_time = time
return total_time
```
3. 性能优化
为了提高查询效率,可以使用缓存技术,将查询结果缓存到内存中,避免多次查询数据库。同时,可以使用索引来加速数据查询,例如在train_station表中为train_no、station和order_no字段添加索引,可以加速列车、站点和站点顺序的查询。此外,还可以使用分页技术来避免查询结果过大的问题,例如将查询结果分页显示,一次只显示部分结果。
阅读全文