乘车线路查询

 
背景
有如下表示乘车线路和站点的数据,要求查询出指定站点之间的所有乘车线路:
USE tempdb
GO
 
-- 模拟数据
SET NOCOUNT ON
IF OBJECT_ID(N'tempdb..#tb') IS NOT NULL
    DROP TABLE #tb
CREATE TABLE #tb(
    id int IDENTITY
        PRIMARY KEY,
    lineID int,
    state nvarchar(10),
    orderid int
)
INSERT #tb(
     lineID, state, orderid)
SELECT 1, N'广州东',UNION ALL
SELECT 1, N'体育中心',UNION ALL
SELECT 1, N'体育西',UNION ALL
SELECT 1, N'烈士陵园',UNION ALL
SELECT 1, N'公园前',UNION ALL
SELECT 1, N'西门口',UNION ALL
SELECT 2, N'火车站',UNION ALL
SELECT 2, N'纪念堂',UNION ALL
SELECT 2, N'公园前',UNION ALL
SELECT 2, N'中大',UNION ALL
SELECT 2, N'客村',UNION ALL
SELECT 2, N'琶洲',UNION ALL
SELECT 2, N'万胜围',UNION ALL
SELECT 3, N'广州东',UNION ALL
SELECT 3, N'体育西',UNION ALL
SELECT 3, N'珠江新城',UNION ALL
SELECT 3, N'客村',UNION ALL
SELECT 3, N'市桥',UNION ALL
SELECT 4, N'万胜围',UNION ALL
SELECT 4, N'金洲', 2
 
CREATE INDEX IX_lineID
    ON #tb(
        lineID)
 
CREATE INDEX IX_state
    ON #tb(
        state)
 
CREATE INDEX IX_orderid
    ON #tb(
        orderid)
GO
 
处理方法:
之前也有发表过一些如何处理这个问题的方法,但效率不是太好。下面的这种方法加上了乘车方向的考虑:同一条线路上,只有两个乘车方向,而且一旦方向了,就不会再反向乘车(因为是从这个方向来,再坐回去是不合理的);如果某个站点可以换到另一条线路,则换乘后的另一条线路也是两个方向乘车。通过乘车方向的控制,减少了算法要搜索的路径。
-- 乘车路线查询
DECLARE
    @state_start nvarchar(10),
    @state_stop nvarchar(10)
SELECT
    @state_start = N'广州东',
    @state_stop = N'中大'
 
-- 查询
IF OBJECT_ID(N'tempdb..#re') IS NOT NULL
    DROP TABLE #re
CREATE TABLE #re(
    ID int IDENTITY
       PRIMARY KEY,
    path nvarchar(max),
    state_count int,
    line_count int,
    start_lineID int,
    start_state nvarchar(10),
    current_lineID int,
    current_state nvarchar(10),
    next_orderid int,
    flag int,
    lineIDs varchar(max),
    level int
)
 
CREATE INDEX IX_current_lineID
    ON #re(
       current_lineID )
 
CREATE INDEX IX_current_state
    ON #re(
       current_state )
 
CREATE INDEX IX_next_orderid
    ON #re(
       next_orderid )
 
CREATE INDEX IX_current_level
    ON #re(
       level )
 
DECLARE
    @level int,
    @rows int
SET
    @level = 0
 
-- 开始
INSERT #re(
    path,
    state_count, line_count,
    start_lineID, start_state,
    current_lineID, current_state,
    next_orderid, flag, lineIDs, level)   
SELECT
    path = CONVERT(nvarchar(max),
           RTRIM(A.lineID) + N'{'
              + RTRIM(A.orderid) + N'.' + A.state
       ),
    state_count = 0,
    line_count = 0,
    start_lineID = A.lineID,
    start_state = A.state,
    current_lineID = A.lineID,
    current_state = A.state,
    next_orderid = A.orderid,
    flag = CASE
           WHEN A.state = @state_stop THEN 0
           ELSE NULL END,
    lineIDs = ',' + RTRIM(A.lineID) + ',',
    level = -(@level + 1)
FROM #tb A
WHERE state = @state_start
SET @rows = @@ROWCOUNT
WHILE @rows > 0
BEGIN
    SELECT
       @level = @level + 1
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 同一LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + A.flag,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE A.flag END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND A.level = @level - 1
       AND A.current_lineID = B.lineID
       AND A.next_orderid = B.orderid
   
    UNION ALL
    -- 不同LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path + N')->'
                  + RTRIM(B.lineID) + N'{'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       line_count = A.line_count + 1,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE NULL END,
       A.lineIDs + RTRIM(B.lineID) + ',',
       level = - @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND state_count = @level - 1
       AND A.current_lineID <> B.lineID
       AND A.current_state = B.state
       AND NOT EXISTS(
              SELECT * FROM #re
              WHERE CHARINDEX(',' + RTRIM(B.lineID) + ',', A.lineIDs) > 0)
    SET @rows = @@ROWCOUNT
 
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 不同LineID 的第站正向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid + 1 = B.orderid
    UNION ALL
    -- 不同LineID 的第站反向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid - 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE - 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid - 1 = B.orderid
 
    SET @rows = @rows + @@ROWCOUNT
END
 
SELECT
-- *,
    path = path + N'}',
    line_count,
    state_count
FROM #re
WHERE flag = 0
 
 
随着经济的飞速发展,汽车越来越多,城市的道路建设远赶不上城市化进程的加快,交通拥堵已成为制约城市发展的重要问题之一。城市公共交通覆盖面广、经济快捷。为了缓解交通压力,必须大力发展公共交通,提高公交服务水平,鼓励和吸引市民选择乘坐公交出行,从而改善交通状况。为此我们设计开发了基于Web的公交查询系统,为乘客出行提供详细全面的信息,进一步提高公交的服务水平。 本文从乘客的角度出发,研究了乘客的出行行为,对公交查询系统进行了需求分析;从系统开发环境、系统目标、设计流程、功能设计、模块设计和数据库设计六个方面进行系统的总体设计;通过抽象公交网络中的站点和线路,建立了公交网络数学模型,讨论了公交网络的最优路径算法,并在此基础上详细介绍了在三种不同目标情况下适合公交查询的最优路径算法;在需求分析、总体设计和基于网络路径最优的公交查询算法探讨基础上,对查询系统进行了详细设计,并成功将三种网络路径算法应用于系统的换乘查询中,系统还实现了线网维护、线路查询、站点查询和标志性地点查询的功能,最后利用武汉市25条线路和400个站点的实验数据,对系统的功能进行了测试,并对公交网络路径的算法时间和查询结果进行了分析。实验证明该系统界面友好、功能完善。
课程设计题目 一、必做题。 1、链表排序 任务 : (1)从文件读入30个无序整数,建立一个单链表,排序输出、再倒序输出。 (2)从文件A读入30个无序整数,建立一个递增的单链表A并输出,从文件B读入30个无序整数,建立一个递增的单链表B并输出,在A中求递增的并集。 (3)从文件读入30个学生成绩(0-100之间),建立一个双向循环链表并输出,调整链表顺序,使所有的及格成绩排在不及格成绩之前,并输出。 2、二叉树的应用 任务 :编程实现二叉树的建立,层次遍历,(递归和非递归方法)先序、中序、后序,二叉树的高度、宽度。二叉排序树的建立、插入、删除; 基本要求:从文件中读入建树信息,树的节点数目不小于20个,树的高度不小于5; 3、校园局域网布线和游历问题 任务 :用无向网表示你所在学校的主要建筑平面图,图中顶点表示主要建筑,图中的边表示建筑之间的道路,存放路径长度信息。要求能够建立校园局域网,所花的代价最小;给出任意建筑之间游历的最短路径。 基本要求: (1) 原始数据存在文件中,方便读入; (2) 建筑物点不小于20个,边不小于30个; (3) 分别用广度优先和深度优先的方法遍历图,起始点定为1号教学楼; (4) 建立校园局域网,要求所花的代价最小; (5) 查询从1号教学楼到其他各点的最短路径; (6) 查询图中任意两个建筑间的最短路径。 4、Hash表应用 任务 :设计散列表实现电话号码查找系统。 基本要求: 1) 设每个记录有下列数据项:电话号码、用户名、地址; 2) 从键盘或文件输入各记录,不少于30个,以电话号码为关键字建立散列表; 3) 采用链地址的方法解决冲突; 4) 查找并显示给定电话号码的记录; 5、排序算法比较 任务 :利用随机函数产生10个样本(其中之一已为正序,之一为倒序),每个样本有20000随机整数,利用直接插入排序、希尔排序,冒泡排序、快速排序、选择排序、堆排序,归并排序(递归和非递归),基数排序八种排序方法进行排序(结果为由小到大的顺序),并统计每一种排序所耗费的平均时间 二、选做题。 1、 运动会分数统计 任务:参加运动会有n个学校,学校编号为1……n。比赛分成m个男子项目,和w个女子项目。项目编号为男子1……m,女子m+1……m+w。不同的项目取前五名或前三名积分;取前五名的积分分别为:7、5、3、2、1,前三名的积分分别为:5、3、2;哪些取前五名或前三名由学生自己设定。(m=10 , w=8 , n=15) 功能要求: 1).可以输入各个项目的前三名或前五名的成绩; 2).能统计各学校总分(用链表); 3).可以按学校编号、学校总分、男女团体总分排序输出(快速、基数); 4).可按学校编号查询学校某个项目的情况;可按项目编号查询前三或前五名的学校。 界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构:学生自己根据系统功能要求自己设计,但是要求运动会的相关数据要存储在数据文件中。 测试数据:要求使用1、全部合法数据;2、局部非法数据。进行程序测试,以保证程序的稳定。测试数据及测试结果请在上交的资料中写明; 2、 迷宫求解 任务:可以读入一个任意大小的迷宫数据,分别用广度和深度搜索的方法求出一条走出迷宫的路径,并将路径输出(最佳路径); 要求:以较为直观的方式显示结果 3、 Huffman编码 任务 :对一篇英文文章,统计各字符出现的次数,实现Huffman编码; 要求:输出每个字符出现的次数和编码,其中求最小权值要求用堆实现; 4、营业窗口队列模拟 任务:实现具有n(n=3)个窗口的现实队列模拟,统计每人的等待时间。 要求: 1). 随机产生顾客的到达时间和服务时间存盘。 2). 利用存盘数据实现队列的插入和删除。 2). 当有顾客离开时,根据队列长度调整队尾。 3). 考虑顾客中途离队的情况。 4). 考虑顾客具有优先级的情况。 5、公交线路提示 任务:建立南京主要公交线路图。 要求:输入任意两站点,给出最佳的乘车线路和转车地点。 路线信息可上网查询 6、家谱管理系统 任务:实现具有下列功能的家谱管理系统 功能要求: 1). 输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以下内容:姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡),也可附加其它信息、但不是必需的。 2). 实现数据的存盘和读盘。 3). 以图形方式显示家谱。 4). 显示第n 代所有人的信息。 5). 按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。 6). 按照出生日期查询成员名单。 7). 输入两人姓名,确定其关系。 8). 某成员添加孩子。 9). 删除某成员(若其还有后代,则一并删除)。 10).修改某成员信息。 11).按出生日期对家谱中所有人排序。 12).打开一家谱时,提示当天生日的健在成员。 要求:建立至少30个成员,以较为直观的方式显示结果,并提供文稿形式以便检查。 界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能。 存储结构:学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中。测试数据:要求使用1、全部合法数据;2、局部非法数据。进行程序测试,以保证程序的稳定。测试数据及测试结果请在上交的资料中写明; 7、算术表达式求值 任务: 一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式起始、结束符是为了方便。编程利用“算符优先法”求算术表达式的值。 要求: (1) 从键盘读入一个合法的算术表达式,输出正确的结果。 (2) 显示输入序列和栈的变化过程。 8、电子小字典 任务:建立一个微型电子字典,实现生词的加入,单词的查找、删除,修改等操作。 数据结构:键树 9、稀疏矩阵相乘 任务:以三元组形式存储稀疏矩阵,实现矩阵相乘 10、平衡二叉树 任务:平衡二叉树的建立、结点的插入和删除。 11、B-树 任务:3阶B-树的结点的插入和删除。 12、编写“连连看”程序。 13、……(自选合适的题目) 成绩评定细则:(优、良、中、及格、不及格五等级) 1. 正确性:程序是否可以运行,结果是否正确(20%) 2. 功能的完备性:是否实现要求的所有子功能(20%) 3. 课程设计报告中的算法说明,课程设计报告中总结(20%) 4. 独立完成情况( 40%) 加分项目: 1.工作量和选题难度 2.可读性:代码编写是否规范,是否便于阅读。如函数、变量命名,‘{ }’的缩进,关键位置适量注释等 3.功能的完善:除要求实现的功能外,完成了其它的功能,实现了功能的完善 4.健壮性:异常处理的情况 5.界面的设计:可视化界面,或者交互良好的DOS界面 6. ……(自荐加分项目) 代码量要求:>=2500行。 代码总量 = 课设题目1 代码量 + 课设题目2 代码量…… 若代码总量低于2500行,则成绩按比例打折。 编程语言:C或C++语言 编程环境:Microsoft Visual C++ 6.0 检查方式:一对一上机检查 总体上检查程序的代码量,正确性,可读性,健壮性,功能的完备性,程序的结构是否合理;根据实际情况进行详细的程序代码检查。 时间安排: 1 上机时间安排 2课程设计检查时间 3 课程设计报告上交时间 课程设计报告要求: 1.课程设计报告封面:包括课题名称、班级、学号、学生姓名、成绩和指导教师; 2.课程设计报告目录:每部分内容所在页码; 3.需求分析:给出每道题的需求; 4.概要设计:给出每道题采用的数据结构,算法设计思想,算法的时间复杂度; 5.详细设计:给出每道题的源程序,并在必要的代码处给出注释; 6.功能测试:给出每道题的测试数据和结果; 7.完成情况:每道题完成部分和未完成部分,自己最满意的部分; 8.代码量:每道题代码的行数和总行数; 9.心得体会:包括课程设计设中遇到的问题,如何解决,编程的体验,感想和建议; 10.课程设计报告的电子文档在检查后一周内上交班长。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值