基于Floyd算法的便捷地铁路线查询系统 数据结构课设 Python课程设计 源代码 实验报告 源码.docx
《基于Floyd算法的便捷地铁路线查询系统 数据结构课设 Python课程设计 源代码 实验报告 源码.docx》由会员分享,可在线阅读,更多相关《基于Floyd算法的便捷地铁路线查询系统 数据结构课设 Python课程设计 源代码 实验报告 源码.docx(17页珍藏版)》请在冰豆网上搜索。
基于Floyd算法的便捷地铁路线查询系统数据结构课设Python课程设计源代码实验报告源码
地铁出行帮助软件
基于Floyd算法的便捷地铁路线查询系统数据结构课设Python课程设计源代码
一.【需求分析】
1.输入
1.1.1输入值来自于UI界面的“出发站:
”、“目的站:
”的两个接收框
1.1.2输入值范围:
来自于“BaseInfo.txt”全部219个站名
2.输出
1.2.1输出:
右侧边栏的文字版的路线,左边在地铁图上的点线表示的出行路线
3.需要处理的数据
1.3.1程序将BaseInfo.txt中的数据(上图只是一部分)通过open函数抓取出来,并存储在两个list型的变量siteNameToNum、siteNumToName中,根据需要再进行后续处理,得到想要的查询路线。
1.3.2将siteNameToNum、siteNumToName中的数据放入矩阵e,之后再进行Floyd算法的计算。
4.程序开发运行选用的环境
1.4.1程序采用python2.7编写。
5.用户界面的设计
1.5.1用户界面采用Python自带图形界面库实现。
打开图形界面后,会看到1个功能按钮和2个输入编辑框,1个输出编辑框,一张地图。
分别在“出发站”“目的站”中输入正确的站点名称之后,点击“确定”功能按钮之后,地图上会显示最短路线,右侧边栏会显示路线信息和时间。
二【数据结构设计】
2.1自定义类设计
2.1.1站点类
siteNameToNum={}#工具1|站名,坐标,所属线路,换乘时间dict类型
siteNumToName={}#工具2|编号,对应站名,坐标,所属路线,换乘时间dict类型
2.1.2矩阵类
e=[[{'lineNo':
-1,'arriveTime':
INF,'transTime':
0,'roadList':
[]}forcolinrange(siteNum)]forrowinrange(siteNum)]#实现使用Floyd算法所用的基础"矩阵"e--list的函数
2.1.3程序整体结构以及各模块的功能描述。
ADT定义:
定义了2个类:
站点类存放各个站点的信息。
矩阵类将站点的信息组成矩阵,用来进行Floyd计算。
主程序流程:
功能1通过直接打开txt文件将站点存入站点类中;
功能2将站点类的信息导入矩阵中,并进行Floyd计算。
功能3调用daoru函数,然后进行对输入的判定,符合会输出相应的信息
功能4调用daoru2函数,然后进行出入栈和排序操作,最后会显示到编辑框
功能5为清空编辑框的信息。
三.【详细设计】
3.1射手榜导入函数
代码:
voidDaoru(int&n,playera[])
{
inti=0;
ifstreamfin("射手榜存档.txt");
intj=0;
intnum=0;
fin>>a[num].name;
fin>>a[num].country;
fin>>a[num].goal;
for(i=1,num=1;i{
fin>>a[num].name;
fin>>a[num].country;
fin>>a[num].goal;
for(j=0;j{
if(a[num].name==a[j].name)
{
a[j].goal+=a[num].goal;
num--;
}
}
num++;
}
n=num;
cout<}
3.2战绩信息导入函数
代码:
voidDaoru2(intnn,zhanjis[])
{
fstreamfin("h:
\\c.txt");
//zhanjis[number];
for(inti=0;ifin>>s[i].country1>>s[i].country2>>s[i].point1>>s[i].point2;
for(inta=0;a
xinxitemp;
fin>>temp.time>>temp.country>>temp.playername;
s[i].jinqiu.insert(a,temp);
}
}
for(intj=0;j//cout<
"<
//s[j].jinqiu.print();
//cout<}
nn=number;
}
3.3局部数据结构说明:
3.3.1链式队列:
template
classLink
{
public:
Tdata;
Link*next;
Link(Tinfo,Link*nextValue=NULL){
data=info;
next=nextValue;
}
Link(){
}
};
//**********************************
template
classlnkList
{
private:
Link*head,*tail;
Link*setPos(constintp);
public:
lnkList();
~lnkList();
boolisEmpty();//检查链表是否为空
voidclear();//将链表存储的内容清除,成为空表
CStringprint(CStringout);
intlength();//返回此链表的当前实际长度
boolappend(constTvalue);//在表尾添加一个元素value,表的长度增1
boolinsert(constintp,constTvalue);//在位置p上插入一个元素value,表的长度增1
boolremove(constintp);//删除位置p上的元素,表的长度减1
boolgetValue(constintp,T&value);//返回位置p的元素值
boolgetPos(int&p,constTvalue);//查找值为value的元素,并返回第1次出现的位置
};
3.3.2链式栈:
template
classlnkStack{
private:
Link*top;
intSsize;
public:
lnkStack(){
top=NULL;
Ssize=0;
}
~lnkStack(){
clear();
}
voidclear(){
while(top!
=NULL){
Link*tmp=top;
top=top->next;
deletetmp;
}
Ssize=0;
}
boolSisEmpty(){
if(Ssize==0)
returntrue;
else
returnfalse;
}
boolpush(Titem){
Link*tmp=newLink(item,top);
top=tmp;
Ssize++;
returntrue;
}
boolpop(T&item)
{
Link*tmp;
if(Ssize==0){
cout<<"栈为空,无法出栈!
"<returnfalse;
}
item=top->data;
tmp=top->next;
deletetop;
top=tmp;
Ssize--;
returntrue;
}
boolrtop(T&item){
if(Ssize==0){
cout<<"栈为空,无法读取!
"<returnfalse;
}
item=top->data;
returntrue;
}
voidSize(){
cout<<"大小为!
"<system("pause");
}
};
3.3.3直接插入排序算法以及重载“〈”:
booloperator<(playera,playerb)
{
if(a.goalreturntrue;
else
returnfalse;
}
//**********************************
voidInsertSort(playerArray[],intn){
playerTempRecord;
inti,j;
for(i=1;iTempRecord=Array[i];
j=i-1;
while(j>=0&&TempRecordArray[j+1]=Array[j];
j=j-1;
}
Array[j+1]=TempRecord;
}
}
3.4主程序(包括图形界面函数)
zhanjis[number];
stringp,q,r;
lnkStackt;
playera[q1];
playerm[q1];
lnkStackt1;
lnkStackt2;
inti=0,i1,ii=0
stringb;
intnum1=0,order;
//*****************************
voidCMyDlg:
:
OnButton1()
{
CStdioFilefp;
fp.Open("h:
\\file.txt",CFile:
:
modeRead);//这时确保edit1填写的文件存在,否则会产生断言错误
CStringstrText,szLine;
while(fp.ReadString(szLine))
{
m_out+=szLine;
m_out=m_out+"\r\n";
}
fp.Close();
UpdateData(false);
}
voidCMyDlg:
:
OnButton2()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
if(dr==false){
Daoru2(number,s);
dr=true;
}
//strings(m_value2.GetBuffer());
p=m_value2.GetBuffer(0);
//m_value2=p;
m_out=_T("_");
CStringtemp1,temp2;
for(intk1=0;k1if(p==s[k1].country1||p==s[k1].country2)
{
m_out=m_out+s[k1].country1.c_str();
temp1.Format("%d",s[k1].point1);
m_out=m_out+temp1;
m_out=m_out+_T(":
");
temp1.Format("%d",s[k1].point2);
m_out=m_out+temp1;
m_out=m_out+s[k1].country2.c_str();
m_out=m_out+"\r\n";
temp2=_T("");
m_out=m_out+s[k1].jinqiu.print(temp2);
m_out=m_out+"\r\n";
}
UpdateData(false);
}
}
voidCMyDlg:
:
OnButton3()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
if(dr==false){
Daoru2(number,s);
dr=true;
}
r=m_value3.GetBuffer(0);
q=m_value4.GetBuffer(0);
m_out=_T("_");
CStringtemp3,temp4;
for(intk=0;kif(q==s[k].country1&&r==s[k].country2||r==s[k].country1&&q==s[k].country2)
{
m_out=m_out+s[k].country1.c_str();
temp3.Format("%d",s[k].point1);
m_out=m_out+temp3;
m_out=m_out+_T(":
");
temp3.Format("%d",s[k].point2);
m_out=m_out+temp3;
m_out=m_out+s[k].country2.c_str();
m_out=m_out+"\r\n";
temp4=_T("");
m_out=m_out+s[k].jinqiu.print(temp4);
m_out=m_out+"\r\n";
}
UpdateData(false);
}
}
voidCMyDlg:
:
OnButton4()
{
Daoru(num1,a);//num1的值就是q2
//TODO:
Addyourcontrolnotificationhandlercodehere
for(i1=0;i1{
t1.push(a[i1]);
}
//cout<<"巴西世界杯射手榜:
"<playertmp;
while(ii!
=q2){
t1.rtop(tmp);
m[ii]=tmp;
t1.pop(tmp);
ii++;
}
InsertSort(m,q2);
inth;
for(h=0;ht2.push(m[h]);
}
intiii=0;
while(iii!
=q2){
t2.rtop(tmp);
CStringtemp5;
m_out=m_out+tmp.name.c_str();
m_out=m_out+"";
m_out=m_out+tmp.country.c_str();
m_out=m_out+"";
temp5.Format("%d",tmp.goal);
m_out=m_out+temp5;
m_out=m_out+"\r\n";
t2.pop(tmp);
iii++;
}
UpdateData(false);
}
voidCMyDlg:
:
OnButton5()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
//break;
UpdateData(true);
m_out=_T("");
m_value2=_T("");
m_value3=_T("");
m_value4=_T("");
UpdateData(false);
}
voidCMyDlg:
:
OnChangeEdit2()
{
//TODO:
IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog:
:
OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
if(m_AtOnce)
{
OnButton2();
}
}
voidCMyDlg:
:
OnChangeEdit1()
{
//TODO:
IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog:
:
OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:
Addyourcontrolnotificationhandlercodehere
}
voidCMyDlg:
:
OnChangeEdit3()
{
//TODO:
IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog:
:
OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
if(m_AtOnce)
{
OnButton2();
}
}
voidCMyDlg:
:
OnChangeEdit4()
{
//TODO:
IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog:
:
OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
if(m_AtOnce)
{
OnButton2();
}
}
四.【测试】
4.1调试分析:
测试中算法经常出现循环错误,开辟存储空间的数量经常与数据量不匹配,由于各场次比赛的进球数不同,导致无法为进球信息类提供固定的存储空间,所以用到了链式存储。
此外,图形用户界面用到MFC编写,由于此前没有MFC的基础,尤其是输入输出的强制类型转换这一块,遇到了极大的阻碍,通过网络上查阅相关算法以及与同学的交流最终实现了相关的我所需要的功能。
算法时间复杂度分析:
功能2,3,4的时间复杂度均为n^2。
4.2.测试结果:
功能1:
功能2:
功能3:
功能4:
功能5为清空,点击后界面会清空,此处就不截图了。
五.【总结与提高】
十周的课程设计结束了,在这次的课程设计中不仅检验了我所学习的知识,也培养了我如何去把握一件事情,如何去做一件事情,又如何完成一件事情的方法和技巧。
在设计过程中,和同学们相互探讨,相互学习,相互监督。
我学会了运筹帷幄,学会了宽容,学会了理解,也学会了做人与处世,这次课程设计对我来说受益良多。
数据结构课程设计是我们专业课程知识综合应用的实践训练,这是我们迈向社会,从事职业工作前一个必不少的过程.“千里之行始于足下”,通过这次课程设计,我深深体会到这句千古名言的真正含义.我今天认真的进行课程设计,学会脚踏实地迈开这一步,就是为明天能稳健地在社会大潮中奔跑打下坚实的基础。
通过这次的课程设计,更是让我深刻认识到自己在学习中的不足,同时也找到了克服这些不足的方法,这也是一笔很大的资源。
在以后的实践过程中,我们应该利用更多的时间去做上机实验,加强自学的能力,多编写程序,相信不久后我们的编程能力都会有很大的提升,能设计出更多的更有创新的作品。