地铁线路查询(easyx)
问题描述:
当一个用户从甲地到乙地时,由于不同需求,就有不同的交通路线,有人希望以最短距离到达,有人希望用最少的换乘次数等。请编写一北京地铁线路查询系统,通过输入起始站、终点站,为用户提供两种或以上决策的交通咨询。
设计要求:
- 提供对地铁线路进行编辑的功能,要求可以添加或删除线路
- 提供多种决策:最短距离,最短时间,最少换乘次数等。
- 中途不考虑等候,拥堵等消耗时间。
- 该系统以人机对话方式进行。用户输入起始站,终点站以及需求原则(需求原则包括最短距离,最短时间,最少换乘次数),系统输出乘车方案:乘几号线,距离,时间,费用,换乘方法等相关信息。
效果图如下:
源码+地铁信息txt文件见github:https://github.com/piedpiperG/Beijing-Subway.git
目录
一,使用的数据结构
1.采用邻接表为存储结构
2.其它数据结构
二,程序中使用的算法和重要函数
1.最短路径算法
2.数据的录入与邻接表初始化
3.easyx展示输出路线
三,地铁线路系统的设计与实现
1.最初构想
2.图的构建
3. 寻找最短路程方案与最短时间方案
4.寻找最少换乘方案
5.站点的删除
6.新增线路
7.easyx界面设计
四,工作流程与案例实例展示
五,总结与不足
六,程序源码如下
一,使用的数据结构
1.采用邻接表为存储结构
用struct封装站点和道路信息
每一个站点为邻接表的顶点,通过函数,查找出两个站点间道路的长度和所用时间
struct Stations
{string name; //站点名称string belongs[20];//所属线路(换乘站的话属于多条线路)Stations* nextStaion;//指向下一站的指针(换乘站可能有多个下一站)
}station[500];struct Roads
{bool ifuse = true;string from; //从哪里来string to; //到哪里去string belong; //所属线路double distance; //道路长度double equaltime; //所用时间
}road[5000];
2.其它数据结构
封装输出信息,在屏幕上打印出路径途径站点与时间,距离,花费
封装每条线路的名称和距离
struct Outans
{vector<string>disans; //最短路程结果数组vector<string>timans; //最短时间结果数组int Odistance; //最短路程距离int distime; //最短路程时间double Otime; //最短时间时间int timdist; //最短时间距离int Dcostmoney; //最短路程花费int Tcostmoney; //最短时间花费
}outans,outans2;struct Sublines
{string name;int speed;
}subline[35];
二,程序中使用的算法和重要函数
1.最短路径算法
在查找最短路时使用dijsktra算法
思想为维护vector<int>vist,vector<int>dist,vector<int>line三个数组得出结果
vist用来记录是否访问了第i个结点
dist用来存储第i个结点到起始点的当前最短距离,初始全设置为INT_MAX
line用来记录按照路径第i个结点上一个结点是什么
循环遍历各个结点,每次取出到起点距离最短且未被vist标记的点,而后通过邻接表更新其它各个点到起始点的最短距离,直到终点也被vist标记时,结束遍历。
此时dist[end]就是最短距离
回溯line[end]即可得出从起始点到终点的最短路径
void dijkstra(string start, string end)
{//最短路径算法辅助数组vector<int>Dvis(Stationnum);//标记访问数组vector<int>Ddis(Stationnum);//标记起始点到每一个端点最短路径数组vector<double>Dtim(Stationnum);//记录最短时间vector<int>Dlin(Stationnum);//记录当前结点上一个结点是什么vector<string>Dans;//输出路线结果for (int i = 1; i < Stationnum; i++) //对数组进行初始化{Ddis[i] = INT_MAX;}Ddis[findStation(start)] = 0; //初始化出发结点Dtim[findStation(start)] = 0;while (Dvis[findStation(end)] != 1) //当终点没有被标记时,持续循环{int cur = Ddismin(Ddis, Dvis); //找到当前到起点最短的路径Stations* sta = station[cur].nextStaion;while (sta) //更新该结点到其它结点的距离{int nex = findStation(sta->name);if (Ddis[nex] > Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].distance){Ddis[nex] = Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].distance;Dtim[nex] = Dtim[cur] + road[findRoad(station[cur].name, station[nex].name)].equaltime;Dlin[nex] = cur;}sta = sta->nextStaion;}Dvis[cur] = 1;}int temp = findStation(end);while (temp != findStation(start)){Dans.push_back(station[temp].name);temp = Dlin[temp];}//Dans.insert(Dans.begin(), start);Dans.push_back(start);string linenote = station[findStation(Dans[0])].belongs[0];outans.disans = Dans;outans.Odistance = Ddis[findStation(end)];outans.distime = Dtim[findStation(end)];double tempdis = (double)outans.Odistance / 1000;outans.Dcostmoney = calculatemoney(tempdis);for (int i = 0; i < Dans.size(); i++){cout << Dans[Dans.size() - i - 1] << "->";}cout << endl;cout << "距离优先:" << endl;cout << "最短距离为:" << Ddis[findStation(end)] << endl;cout << "花费时间为:" << Dtim[findStation(end)] << endl;cout << "所需花费为:" << outans.Dcostmoney << endl;
}
2.数据的录入与邻接表初始化
根据北京地铁官网给出的各个站点之间间距如下图:
故选择将此表复制粘贴到本地为txt文件
然后用fstream库中的函数将文本数据以行为单位,进行录入,然后使用函数istringstream将每一行的三个字符串拆开,依次初始化站点和距离长度。
运用链表插入的知识构建邻接表。
void readfile1()
{//1、包含头文件//2、创建流对象ifstream ifs;//3、打开文件并且判断是否打开成功ifs.open("D:\\学校事务\\数据结构与算法课程设计\\地铁2.txt", ios::in);if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}//存储数据用到的中介值string linename;//线路名称int cnt1 = 1;//车站编号int cnt2 = 1;//道路编号int formStation;//前车站编号int lateStation;//后车编号//4、读数据string buf;while (getline(ifs, buf)) //对每一行的处理{//cout << buf << endl;if (buf[0] == '#') //当这一行是线路时,只存储线路{linename = buf;continue;}istringstream is(buf); //将is绑定到bufstring s;int tempcnt = 1;while (is >> s){if (tempcnt == 1) //第一个字符串{if (findStation(s) == -1) //没有存储这个站点{station[cnt1].name = s;int i = 0;while (station[cnt1].belongs[i] != "")i++;station[cnt1].belongs[i] = linename;formStation = cnt1;cnt1++;}else{int j = findStation(s);int i = 0;while (station[j].belongs[i] != "")i++;station[j].belongs[i] = linename;formStation = j;}tempcnt = 2;}else if (tempcnt == 2){int j = cnt1;bool ok = false;if (findStation(s) == -1) //没有存储这个站点{station[cnt1].name = s;ok = true;}else{j = findStation(s);}int i = 0;while (station[j].belongs[i] != "")i++;station[j].belongs[i] = linename; //添加所属线路insertStation(formStation, j);//插入前一个结点的邻接表insertStation(j, formStation);lateStation = j; //记录后车编号if (ok)cnt1++;tempcnt = 3;}else if (tempcnt == 3){if (findRoad(station[formStation].name, station[lateStation].name) == -1){road[cnt2].from = station[formStation].name;road[cnt2].to = station[lateStation].name;road[cnt2].distance = atoi(s.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));cnt2++;road[cnt2].to = station[formStation].name;road[cnt2].from = station[lateStation].name;road[cnt2].distance = atoi(s.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));cnt2++;}tempcnt = 1;}//cout << s << endl;}}//5、关闭文件ifs.close();
}
3.easyx展示输出路线
如何将已经录入的信息通过easyx展示在屏幕上是一个完全自己通过几个函数摸索出来的东西。
这里主要讲述如何将已经查找到的路径工整打印在屏幕上。
难点1:文字在背景图片的干扰下看不清
解决方法:在文字背后先画出彩色方框,来衬托文字的存在
难点2:easyx中的输出函数outtextxy只能将文字按照坐标打印在屏幕上,如何确保各个字符串有序排列,不重叠,不超出屏幕。
解决方法:设置变量对坐标进行处理,根据每一个字符串的长度来调整横纵坐标的情况,在将要超出屏幕宽度时控制纵坐标参数达到自动换行
难点3:距离优先,时间优先多种选择方式如何展示
解决方法:设置翻页功能,展示不下就在下一页展示
void display()
{int lengthcnt = 2;//纵向列数int lengthlim=35;//纵向单位//int widthcnt = 0;//横向行数int widthlim = 6;//横向单位int width = 0;bool stopsignal = false;//停止打印最短路路径标志while (!stopsignal){string templine = "";for (int i = outans.disans.size()-1; i >= 0; i--){if (width > 900){lengthcnt++;width = 0;}if (i == outans.disans.size() - 1){templine = findbelong(outans.disans[i], outans.disans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;} //输出打印几号线setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.disans[i].size();fillroundrect(width, lengthlim * lengthcnt, width + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width , lengthlim * lengthcnt, outans.disans[i].c_str());width += 13 * strlength + widthlim;//widthcnt++;if (i > 0 && findbelong(outans.disans[i], outans.disans[i - 1]) != templine){templine = findbelong(outans.disans[i], outans.disans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength1 = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength1 * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;width = 0;setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.disans[i].size();fillroundrect(width + 0, lengthlim * lengthcnt, width + 0 + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width + 0, lengthlim * lengthcnt, outans.disans[i].c_str());//widthcnt++;width += strlength * 13 + widthlim;} //输出打印几号线}stopsignal = true;}setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 10, 700 + 300, 10 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 10, "总距离:");char grade[100] = "";sprintf(grade, "%d", outans.Odistance);outtextxy(800, 10, grade);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 40, 700 + 300, 40 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 40, "预计时间:");char grade1[100] = "";sprintf(grade1, "%d", outans.distime);outtextxy(825, 40, grade1);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 70, 700 + 300, 70 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 70, "预计花费:");char grade2[100] = "";sprintf(grade2, "%d", outans.Dcostmoney);outtextxy(825, 70, grade2);setbkmode(TRANSPARENT);setfillcolor(YELLOW);fillroundrect(200, 50, 200 + 210, 50 + 35, 10, 10);settextstyle(35, 0, "宋体");setbkmode(TRANSPARENT);settextcolor(CYAN);outtextxy(200, 50, "最短距离策略");/*setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);fillroundrect(10, 100, 10 + 75, 100 + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(10, 100, "西直门");*/
}
三,地铁线路系统的设计与实现
1.最初构想
考虑到如此庞大的数据量,邻接矩阵不再适用,很快确定了把邻接表作为存储结构
构建结点时,考虑要不要把普通站设为一种结点,始发站设为一种结点,终点站再设为一种结点,然而这样一来太过复杂,在后序的算法中一个查找就需要好几种数据结构。所以想到干脆一种数据结构,但要尽可能详尽包含所有的信息,所以便设计了Stations和Roads两种完备的数据结构。
看似有些臃肿,但实则方便,后序的所有功能都可以通过另写函数来实现,如我们虽然没有标记哪一站是换乘站,但知道每一站的所属线路,写一个哈希函数就可以找出相邻两站共同的所属线路从而确认是否换乘。
数据存储部分:
struct Stations
{string name; //站点名称string belongs[20];//所属线路(换乘站的话属于多条线路)Stations* nextStaion;//指向下一站的指针(换乘站可能有多个下一站)
}station[500];
struct Roads
{bool ifuse = true;string from; //从哪里来string to; //到哪里去string belong; //所属线路double distance; //道路长度double equaltime; //所用时间
}road[5000];
struct Sublines
{string name;int speed;
}subline[35];
2.图的构建
通过链表的插入知识和文件读取很轻松的构建了整个地铁网络图,只要确定好了存储的数据结构,在图的构建上并不困难
3. 寻找最短路程方案与最短时间方案
刚开始的想法是写一个bfs或dfs搜索,将起点到终点所有可能的路线搜出来,然后想比较什么比较什么不就可以了,一个bfs函数很快写好了,但由于北京地铁庞大的数据量,稍微远一点的距离往往需要长达4,5分钟才能得出结果... ...遂放弃
而后采用效率高得多的最短路径算法dijkstra,最短时间就是将原本的最短路径参数除以速度,所以两个方案共用同一种函数即可。
4.寻找最少换乘方案
最少换乘本质上也用的是dijkstra算法,只不过是单源最短路径。
如果两个站点在一条线路上,那么就将两个站点之间的距离设为1,否则设为9999,这样搜出来的路径就是最少换乘要达到的路径了
这里另开辟了一个邻接矩阵来初始化新的数据
//计算最少换乘用图
vector<vector<int>>Map(Stationnum, vector<int>(Stationnum));void initMap()
{for (int i = 1; i < Stationnum; i++){for (int j = 1; j < Stationnum; j++){if (findbelong(station[i].name, station[j].name) != ""){Map[i][j] = 1;}else{Map[i][j] = 9999;}}}
}
5.站点的删除
因为各个站点之间是依靠邻接表指针相联系的,所以站点的删除上我们直接让站点的指针指向空,表示此路不通即可
void forbiddenstation(string name)
{int cur = findStation(name);Stations* sta = station[cur].nextStaion;while (sta){int nex = findRoad(station[cur].name, sta->name);road[nex].ifuse = false;sta = sta->nextStaion;}station[0].nextStaion = emptystation.nextStaion;station[cur].nextStaion = station[0].nextStaion;}
6.新增线路
新增线路的函数内容来源于初始化数据的readfile1,原理相同,就是把从txt文件中读取数据,变成了手动输入数据,而后新增节点存储在图中。
void insertroad(string start, string end, string length)
{if (findStation(end) == -1) //没有存储这个站点{station[insistnum].name = end;insistnum++;}int s = findStation(start);int e = findStation(end);insertStation(s, e);//插入前一个结点的邻接表insertStation(e, s);road[staynum].from = start;road[staynum].to = end;road[staynum].distance = atoi(length.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));staynum++;road[staynum].to = start;road[staynum].from = end;road[staynum].distance = atoi(length.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));staynum++;}
7.easyx界面设计
简单了解了easyx的几个函数和使用方法,通过向easyx写出的贪吃蛇小游戏原理学习,制作出了这个简易的easyx界面。
首先在背景贴上背景图
而后其它的动画文字都是在不断地刷新的,在一个while(true)循环中
所以我们加入一个Mode的判断量
通过if(Mode)的方式,就可以实现界面跳转的功能。
而后使用函数判断按键与鼠标是否参与,就制作出了一个简单风格的页面。
部分实现代码:
while (1){BeginBatchDraw(); //缓冲区打印,防止闪屏cleardevice();//刷新putimage(0, 0, &background);//绘制图像到屏幕,图片左上角坐标为(0,0)while (_kbhit())//如果有按键则进入,否则不进入循环{char userkey = 0;userkey = _getch();if (userkey == VK_ESCAPE){Mode = 0;}}if (Mode == 0){TCHAR s[50] = "1.查找线路";TCHAR s1[50] = "2.关停站点";TCHAR s2[50] = "3.关停线路";TCHAR s3[50] = "4.插入路线";button(391, 200, 170, 50, s);button(391, 300, 170, 50, s1);button(391, 400, 170, 50, s2);button(391, 500, 170, 50, s3);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN:if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 200 && msg.y <= 200 + 50){cout << "!" << endl;Mode = 1;//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 300 && msg.y <= 300 + 50){cout << "?" << endl;Mode = 2;//在此处写下按钮点击时要执行的函数,实现相应的功能 }if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 400 && msg.y <= 400 + 50){cout << "@" << endl;Mode = 3;//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 500 && msg.y <= 500 + 50){cout << "&" << endl;Mode = 4;//在此处写下按钮点击时要执行的函数,实现相应的功能}break;default:break;}}}
四,工作流程与案例实例展示
运行程序,进入界面菜单:
输入你想搜索的最短线路,结果会在旁边显示,如果输入不正确,会弹窗提示
点击确认,得到结果,通过右下角的上下翻页键查看不同的策略方案
而后三个功能和此功能有着相同的界面和使用方法
需要注意的是,在添加路线功能中不允许添加一条独立的路线,起始站点必须是地图中已有的站点,终点站可以是自己新建的站点。
五,总结与不足
此次大作业第一眼看起来任务量很大且难度很大,但分模块操作起来发现过程比想象的容易得多,并且对于基础数据结构和算法较为熟练运用后,大的问题拆分成小的函数逐个解决即可。自己摸索easyx的过程很有趣,做出来的页面虽然看起来像上个世纪的东西但仍然会给我惊喜。由于受时间所限,还有很多没有完善的地方,比如最少换乘方案还没有给出完备的过程和距离时间,界面如果不采用画图,自己做贴画按钮一定更好看,想加一个鼠标移动到按钮上方出现的特效来不及了。总体来说大致的功能完成的还是不错的,暴露出规划不明确,函数乱写,到后来开摆式的复制粘贴等问题都是不错的经验。
六,程序源码如下
head.h
#include<iostream>
#include<stdlib.h>
#include<string>
#include<fstream>
#include <sstream> //使用istringstream所需要的头文件
#include <cassert>
#include<queue>
#include<vector>
#include<time.h>
#include<graphics.h>
#include<conio.h>
#include<easyx.h>
#include<windows.h>
#include<mmsystem.h>
#include <unordered_map>
using namespace std;
/*采用邻接表作为存储结构构建站点Station和道路Road两种结构体*///站点结构体如下:
int Stationnum = 356;
int insistnum = 352;
struct Stations
{string name; //站点名称string belongs[20];//所属线路(换乘站的话属于多条线路)Stations* nextStaion;//指向下一站的指针(换乘站可能有多个下一站)
}station[500];
Stations emptystation;//计算最少换乘用图
vector<vector<int>>Map(Stationnum, vector<int>(Stationnum));//道路结构体如下:
int Roadnum = 800;
int staynum = 796;
struct Roads
{bool ifuse = true;string from; //从哪里来string to; //到哪里去string belong; //所属线路double distance; //道路长度double equaltime; //所用时间
}road[5000];int Sublinenum = 30;
//记录各条线路速度
struct Sublines
{string name;int speed;
}subline[35];//记录搜索时的方式
struct pos
{string Loc; //所在位置int Distance;//行程距离int Changetime;//换乘次数int Costtime;//花费时间vector<string>Rember;//记录途径地点
};//存储结果的结构体
struct Outans
{vector<string>disans; //最短路程结果数组vector<string>timans; //最短时间结果数组int Odistance; //最短路程距离int distime; //最短路程时间double Otime; //最短时间时间int timdist; //最短时间距离int Dcostmoney; //最短路程花费int Tcostmoney; //最短时间花费
}outans,outans2;//初始化邻接表和道路
void readfile1();
//初始化各个线路的速度和时间
void readfile2();
//寻找到车站的编号
int findStation(string str);
//寻找到道路的编号
int findRoad(string start, string end);
//构建邻接表,插入结点
void insertStation(int start, int end);
//打印邻接表
void print1();
//打印道路
void print2();
//深搜给出解决方案
void bfs(string start, string end);
//最短路径搜索
void dijkstra(string start, string end);
//最短时间搜索
void dijkstra2(string start, string end);
//最少换乘搜索
void dijkstra3(string start, string end);
//最短路函数种搜索距离最小点函数
int Ddismin(vector<int>arr, vector<int>brr);
int Ddismin2(vector<double>arr, vector<int>brr);
//返回线路对应的速度
double findspeed(string str);
//返回道路所属的线路
string findbelong(string start, string end);
//最少换乘路线
void dfs(string start, string end);
//easyx按键
void button(int x, int y, int w, int h, TCHAR* text);
//展示优先路程路径
void display();
//展示优先时间路径
void display2();
//展示最少换乘路径
void display3();
//计算里程花费的钱
int calculatemoney(double n);
//弹出错误
bool showerror(string name);
//停用站点
void forbiddenstation(string name);
//停用线路
void forbiddenroad(string name);
//初始化Map
void initMap();
//添加线路
void insertroad(string start, string end, string length);
function1.h
#include"head.h"void readfile1()
{//1、包含头文件//2、创建流对象ifstream ifs;//3、打开文件并且判断是否打开成功ifs.open("./resource/地铁2.txt", ios::in);if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}//存储数据用到的中介值string linename;//线路名称int cnt1 = 1;//车站编号int cnt2 = 1;//道路编号int formStation;//前车站编号int lateStation;//后车编号//4、读数据string buf;while (getline(ifs, buf)) //对每一行的处理{//cout << buf << endl;if (buf[0] == '#') //当这一行是线路时,只存储线路{linename = buf;continue;}istringstream is(buf); //将is绑定到bufstring s;int tempcnt = 1;while (is >> s){if (tempcnt == 1) //第一个字符串{if (findStation(s) == -1) //没有存储这个站点{station[cnt1].name = s;int i = 0;while (station[cnt1].belongs[i] != "")i++;station[cnt1].belongs[i] = linename;formStation = cnt1;cnt1++;}else{int j = findStation(s);int i = 0;while (station[j].belongs[i] != "")i++;station[j].belongs[i] = linename;formStation = j;}tempcnt = 2;}else if (tempcnt == 2){int j = cnt1;bool ok = false;if (findStation(s) == -1) //没有存储这个站点{station[cnt1].name = s;ok = true;}else{j = findStation(s);}int i = 0;while (station[j].belongs[i] != "")i++;station[j].belongs[i] = linename; //添加所属线路insertStation(formStation, j);//插入前一个结点的邻接表insertStation(j, formStation);lateStation = j; //记录后车编号if (ok)cnt1++;tempcnt = 3;}else if (tempcnt == 3){if (findRoad(station[formStation].name, station[lateStation].name) == -1){road[cnt2].from = station[formStation].name;road[cnt2].to = station[lateStation].name;road[cnt2].distance = atoi(s.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));cnt2++;road[cnt2].to = station[formStation].name;road[cnt2].from = station[lateStation].name;road[cnt2].distance = atoi(s.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));cnt2++;}tempcnt = 1;}//cout << s << endl;}}//5、关闭文件ifs.close();
}void readfile2(){//1、包含头文件//2、创建流对象ifstream ifs;//3、打开文件并且判断是否打开成功ifs.open("./resource/地铁平均速度1.txt", ios::in);if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}//统计地铁编号int cnt = 1;//4、读数据string buf;while (getline(ifs, buf)) //对每一行的处理{istringstream is(buf); //将is绑定到bufstring s;while (is >> s){if (s[0] == '#')subline[cnt].name = s;else{subline[cnt].speed = atoi(s.c_str());}}cnt++;}//5、关闭文件ifs.close();for (int i = 1; i < Roadnum; i++){road[i].equaltime = road[i].distance / findspeed(findbelong(road[i].from, road[i].to));}
}int findStation(string str)
{for (int i = 1; i < Stationnum; i++){if (station[i].name == str)return i;}return -1; //当不存在此站点时
}int findRoad(string start, string end)
{for (int i = 1; i < Roadnum; i++){if (road[i].from == start && road[i].to == end)return i;}return -1; //当不存在这个道路时
}void insertStation(int start, int end)
{if (station[start].nextStaion == NULL){Stations* newsta = new Stations;newsta->name = station[end].name;station[start].nextStaion = newsta;newsta->nextStaion = NULL;}else{Stations* newsta = new Stations;newsta->name = station[end].name;newsta->nextStaion = station[start].nextStaion;station[start].nextStaion = newsta; //!!!}
}void print1()
{for (int i = 1; i <= Stationnum; i++){cout << station[i].name;Stations* sta = station[i].nextStaion;while (sta){cout << "->" << sta->name;sta = sta->nextStaion;}cout << endl;}
}void print2()
{for (int i = 1; i <= Roadnum; i++){cout << road[i].from << "->" << road[i].to << " need " << road[i].distance << "and" << road[i].equaltime << endl;}
}void bfs(string start, string end)
{vector<int>vis(300);queue<pos>que;pos cur;pos ans[2000];pos res;int cnt = 1;cur.Loc = start;cur.Distance = 0;cur.Rember.push_back(start);vis[findStation(start)] = 1;que.push(cur);while (!que.empty()){cur = que.front();que.pop();if (cur.Loc == end) //找到了目的地{ans[cnt] = cur;cnt++;break;}Stations* sta = station[findStation(cur.Loc)].nextStaion;while (sta){pos nex;nex.Loc = sta->name;sta = sta->nextStaion;if (!vis[findStation(nex.Loc)]){nex.Distance = road[findRoad(cur.Loc, nex.Loc)].distance + cur.Distance;nex.Rember = cur.Rember;nex.Rember.push_back(nex.Loc);que.push(nex);}}}res.Distance = INT_MAX;for (int i = 1; i <= cnt - 1; i++){if (ans[i].Distance < res.Distance)res = ans[i];}for (int i = 0; i < res.Rember.size(); i++)cout << res.Rember[i] << "->";cout << endl;
}void dijkstra(string start, string end)
{//最短路径算法辅助数组vector<int>Dvis(Stationnum);//标记访问数组vector<int>Ddis(Stationnum);//标记起始点到每一个端点最短路径数组vector<double>Dtim(Stationnum);//记录最短时间vector<int>Dlin(Stationnum);//记录当前结点上一个结点是什么vector<string>Dans;//输出路线结果for (int i = 1; i < Stationnum; i++) //对数组进行初始化{Ddis[i] = INT_MAX;}Ddis[findStation(start)] = 0; //初始化出发结点Dtim[findStation(start)] = 0;while (Dvis[findStation(end)] != 1) //当终点没有被标记时,持续循环{int cur = Ddismin(Ddis, Dvis); //找到当前到起点最短的路径Stations* sta = station[cur].nextStaion;while (sta) //更新该结点到其它结点的距离{int nex = findStation(sta->name);if (Ddis[nex] > Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].distance){Ddis[nex] = Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].distance;Dtim[nex] = Dtim[cur] + road[findRoad(station[cur].name, station[nex].name)].equaltime;Dlin[nex] = cur;}sta = sta->nextStaion;}Dvis[cur] = 1;}int temp = findStation(end);while (temp != findStation(start)){Dans.push_back(station[temp].name);temp = Dlin[temp];}//Dans.insert(Dans.begin(), start);Dans.push_back(start);string linenote = station[findStation(Dans[0])].belongs[0];outans.disans = Dans;outans.Odistance = Ddis[findStation(end)];outans.distime = Dtim[findStation(end)];double tempdis = (double)outans.Odistance / 1000;outans.Dcostmoney = calculatemoney(tempdis);for (int i = 0; i < Dans.size(); i++){cout << Dans[Dans.size() - i - 1] << "->";}cout << endl;cout << "距离优先:" << endl;cout << "最短距离为:" << Ddis[findStation(end)] << endl;cout << "花费时间为:" << Dtim[findStation(end)] << endl;cout << "所需花费为:" << outans.Dcostmoney << endl;
}void dijkstra2(string start, string end)
{//最短路径算法辅助数组vector<int>Dvis(Stationnum);//标记访问数组vector<double>Ddis(Stationnum);//标记起始点到每一个端点最短路径数组vector<int>Dtim(Stationnum);vector<int>Dlin(Stationnum);//记录当前结点上一个结点是什么vector<string>Dans;//输出路线结果for (int i = 1; i < Stationnum; i++) //对数组进行初始化{Ddis[i] = INT_MAX;}Ddis[findStation(start)] = 0; //初始化出发结点Dtim[findStation(start)] = 0;while (Dvis[findStation(end)] != 1) //当终点没有被标记时,持续循环{int cur = Ddismin2(Ddis, Dvis); //找到当前到起点最短的路径Stations* sta = station[cur].nextStaion;while (sta) //更新该结点到其它结点的距离{int nex = findStation(sta->name);if (Ddis[nex] > Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].equaltime){Ddis[nex] = Ddis[cur] + road[findRoad(station[cur].name, station[nex].name)].equaltime;Dtim[nex] = Dtim[cur] + road[findRoad(station[cur].name, station[nex].name)].distance;Dlin[nex] = cur;}sta = sta->nextStaion;}Dvis[cur] = 1;}int temp = findStation(end);while (temp != findStation(start)){Dans.push_back(station[temp].name);temp = Dlin[temp];}//Dans.insert(Dans.begin(), start);Dans.push_back(start);string linenote = station[findStation(Dans[0])].belongs[0];outans.timans = Dans;outans.Otime = Ddis[findStation(end)];outans.timdist = Dtim[findStation(end)];outans.Tcostmoney = calculatemoney(double(outans.timdist) / 1000);for (int i = 0; i < Dans.size(); i++){cout << Dans[Dans.size() - i - 1] << "->";}cout << endl;cout << "时间优先:" << endl;cout << "所用距离为:" << Dtim[findStation(end)] << endl;cout << "最短时间为:" << Ddis[findStation(end)] << endl;cout << "所需花费为:" << outans.Tcostmoney << endl;
}void dijkstra3(string start, string end)
{vector<int>vis(Stationnum);vector<int>dis(Stationnum);vector<int>lin(Stationnum);vector<string>ans;for (int i = 1; i < Stationnum; i++){dis[i] = INT_MAX;}dis[findStation(start)] = 0;while (vis[findStation(end)] != 1){int cur = Ddismin(dis, vis);for (int i = 1; i < Stationnum; i++){int nex = i;if (dis[nex] > dis[cur] + Map[cur][nex]){dis[nex] = dis[cur] + Map[cur][nex];lin[nex] = cur;}vis[cur] = 1;}}int temp = findStation(end);while (temp != findStation(start)){ans.push_back(station[temp].name);temp = lin[temp];}ans.push_back(start);outans2.timans = ans;for (int i = 0; i < ans.size(); i++){cout << ans[ans.size() - i - 1] << "->";}
}int Ddismin(vector<int>arr, vector<int>brr)
{int temp = INT_MAX;int ans = 0;for (int i = 1; i < arr.size(); i++){if (arr[i] < temp && brr[i] != 1){temp = arr[i];ans = i;}}return ans;
}
int Ddismin2(vector<double>arr, vector<int>brr)
{int temp = INT_MAX;int ans = 0;for (int i = 1; i < arr.size(); i++){if (arr[i] < temp && brr[i] != 1){temp = arr[i];ans = i;}}return ans;
}double findspeed(string str)
{for (int i = 1; i < Sublinenum; i++){if (subline[i].name == str)return subline[i].speed;}return -1;
}string findbelong(string start, string end)
{unordered_map<string, int>hash;int cur = findStation(start);int nex = findStation(end);for (int i = 0; i < 10; i++){hash[station[cur].belongs[i]]++;}for (int i = 0; i < 10; i++){if (hash[station[nex].belongs[i]] > 0){return station[nex].belongs[i];}}return "";
}//void dfs()
//{
//
//}
int calculatemoney(double n)
{if (n <= 6)return 3;else if (n > 6 && n <= 12)return 4;else if (n > 12 && n <= 22)return 5;else if (n > 22 && n <= 32)return 6;else{return (n - 32) / 20 + 1 + 6;}}void initMap()
{for (int i = 1; i < Stationnum; i++){for (int j = 1; j < Stationnum; j++){if (findbelong(station[i].name, station[j].name) != ""){Map[i][j] = 1;}else{Map[i][j] = 9999;}}}/*for (int i = 1; i < Stationnum; i++){for (int j = 2; j < Stationnum; j++){cout << Map[i][j] << " ";}cout << endl;}*/
}void insertroad(string start, string end, string length)
{if (findStation(end) == -1) //没有存储这个站点{station[insistnum].name = end;insistnum++;}int s = findStation(start);int e = findStation(end);insertStation(s, e);//插入前一个结点的邻接表insertStation(e, s);road[staynum].from = start;road[staynum].to = end;road[staynum].distance = atoi(length.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));staynum++;road[staynum].to = start;road[staynum].from = end;road[staynum].distance = atoi(length.c_str());//road[cnt2].equaltime = road[cnt2].distance / findspeed(findbelong(station[formStation].name, station[lateStation].name));staynum++;}void button(int x, int y, int w, int h, TCHAR* text)
{setbkmode(TRANSPARENT);setfillcolor(LIGHTGREEN);fillroundrect(x, y, x + w, y + h, 10, 10);// 输出字符串(MBCS 字符集)TCHAR s1[] = "楷体";settextstyle(30, 0, s1);TCHAR s[50] = "hello";int tx = x + (w - textwidth(text)) / 2;int ty = y + (h - textheight(text)) / 2;outtextxy(tx, ty, text);}void display()
{int lengthcnt = 2;//纵向列数int lengthlim = 35;//纵向单位//int widthcnt = 0;//横向行数int widthlim = 6;//横向单位int width = 0;bool stopsignal = false;//停止打印最短路路径标志while (!stopsignal){string templine = "";for (int i = outans.disans.size() - 1; i >= 0; i--){if (width > 900){lengthcnt++;width = 0;}if (i == outans.disans.size() - 1){templine = findbelong(outans.disans[i], outans.disans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;} //输出打印几号线setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.disans[i].size();fillroundrect(width, lengthlim * lengthcnt, width + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width, lengthlim * lengthcnt, outans.disans[i].c_str());width += 13 * strlength + widthlim;//widthcnt++;if (i > 0 && findbelong(outans.disans[i], outans.disans[i - 1]) != templine){templine = findbelong(outans.disans[i], outans.disans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength1 = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength1 * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;width = 0;setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.disans[i].size();fillroundrect(width + 0, lengthlim * lengthcnt, width + 0 + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width + 0, lengthlim * lengthcnt, outans.disans[i].c_str());//widthcnt++;width += strlength * 13 + widthlim;} //输出打印几号线}stopsignal = true;}setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 10, 700 + 300, 10 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 10, "总距离:");char grade[100] = "";sprintf(grade, "%d", outans.Odistance);outtextxy(800, 10, grade);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 40, 700 + 300, 40 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 40, "预计时间:");char grade1[100] = "";sprintf(grade1, "%d", outans.distime);outtextxy(825, 40, grade1);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 70, 700 + 300, 70 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 70, "预计花费:");char grade2[100] = "";sprintf(grade2, "%d", outans.Dcostmoney);outtextxy(825, 70, grade2);setbkmode(TRANSPARENT);setfillcolor(YELLOW);fillroundrect(200, 50, 200 + 210, 50 + 35, 10, 10);settextstyle(35, 0, "宋体");setbkmode(TRANSPARENT);settextcolor(CYAN);outtextxy(200, 50, "最短距离策略");/*setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);fillroundrect(10, 100, 10 + 75, 100 + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(10, 100, "西直门");*/
}void display2(){int lengthcnt = 2;//纵向列数int lengthlim = 35;//纵向单位//int widthcnt = 0;//横向行数int widthlim = 6;//横向单位int width = 0;bool stopsignal = false;//停止打印最短路路径标志while (!stopsignal){string templine = "";for (int i = outans.timans.size() - 1; i >= 0; i--){if (width > 900){lengthcnt++;width = 0;}if (i == outans.timans.size() - 1){templine = findbelong(outans.timans[i], outans.timans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;} //输出打印几号线setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.timans[i].size();fillroundrect(width, lengthlim * lengthcnt, width + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width, lengthlim * lengthcnt, outans.timans[i].c_str());width += 13 * strlength + widthlim;//widthcnt++;if (i > 0 && findbelong(outans.timans[i], outans.timans[i - 1]) != templine){templine = findbelong(outans.timans[i], outans.timans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength1 = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength1 * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;width = 0;setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans.timans[i].size();fillroundrect(width + 0, lengthlim * lengthcnt, width + 0 + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width + 0, lengthlim * lengthcnt, outans.timans[i].c_str());//widthcnt++;width += strlength * 13 + widthlim;} //输出打印几号线}stopsignal = true;}setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 10, 700 + 300, 10 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 10, "总距离:");char grade[100] = "";sprintf(grade, "%d", outans.timdist);outtextxy(800, 10, grade);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 40, 700 + 300, 40 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 40, "预计时间:");char grade1[100] = "";sprintf(grade1, "%d", (int)outans.Otime);outtextxy(825, 40, grade1);setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 70, 700 + 300, 70 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 70, "预计花费:");char grade2[100] = "";sprintf(grade2, "%d", outans.Tcostmoney);outtextxy(825, 70, grade2);setbkmode(TRANSPARENT);setfillcolor(MAGENTA);fillroundrect(200, 50, 200 + 210, 50 + 35, 10, 10);settextstyle(35, 0, "宋体");setbkmode(TRANSPARENT);settextcolor(LIGHTCYAN);outtextxy(200, 50, "最短时间策略");/*setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);fillroundrect(10, 100, 10 + 75, 100 + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(10, 100, "西直门");*/
}void display3()
{int lengthcnt = 2;//纵向列数int lengthlim = 35;//纵向单位//int widthcnt = 0;//横向行数int widthlim = 6;//横向单位int width = 0;bool stopsignal = false;//停止打印最短路路径标志while (!stopsignal){string templine = "";for (int i = outans2.timans.size() - 1; i >= 0; i--){if (width > 900){lengthcnt++;width = 0;}if (i == outans2.timans.size() - 1){templine = findbelong(outans2.timans[i], outans2.timans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;} //输出打印几号线setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans2.timans[i].size();fillroundrect(width, lengthlim * lengthcnt, width + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width, lengthlim * lengthcnt, outans2.timans[i].c_str());width += 13 * strlength + widthlim;//widthcnt++;if (i > 0 && findbelong(outans2.timans[i], outans2.timans[i - 1]) != templine){templine = findbelong(outans2.timans[i], outans2.timans[i - 1]);lengthcnt++;setbkmode(TRANSPARENT);setfillcolor(LIGHTRED);int strlength1 = templine.size();fillroundrect(20, lengthlim * lengthcnt, 20 + strlength1 * 15, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "黑体");setbkmode(TRANSPARENT);settextcolor(WHITE);outtextxy(20, lengthlim * lengthcnt, templine.c_str());lengthcnt++;//widthcnt = 0;width = 0;setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);int strlength = outans2.timans[i].size();fillroundrect(width + 0, lengthlim * lengthcnt, width + 0 + 13 * strlength, lengthlim * lengthcnt + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(width + 0, lengthlim * lengthcnt, outans2.timans[i].c_str());//widthcnt++;width += strlength * 13 + widthlim;} //输出打印几号线}stopsignal = true;}setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 10, 700 + 300, 10 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 10, "总距离:");/*char grade[100] = "";sprintf(grade, "%d", outans.timdist);outtextxy(800, 10, grade);*/setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 40, 700 + 300, 40 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 40, "预计时间:");/*char grade1[100] = "";sprintf(grade1, "%d", (int)outans.Otime);outtextxy(825, 40, grade1);*/setbkmode(TRANSPARENT);setfillcolor(WHITE);fillroundrect(700, 70, 700 + 300, 70 + 25, 10, 10);settextstyle(25, 0, "隶书");setbkmode(TRANSPARENT);settextcolor(BLACK);outtextxy(700, 70, "预计花费:");/*char grade2[100] = "";sprintf(grade2, "%d", outans.Tcostmoney);outtextxy(825, 70, grade2);*/setbkmode(TRANSPARENT);setfillcolor(LIGHTGRAY);fillroundrect(200, 50, 200 + 210, 50 + 35, 10, 10);settextstyle(35, 0, "宋体");setbkmode(TRANSPARENT);settextcolor(LIGHTCYAN);outtextxy(200, 50, "最少换乘策略");/*setbkmode(TRANSPARENT);setfillcolor(LIGHTBLUE);fillroundrect(10, 100, 10 + 75, 100 + 25, 10, 10);settextstyle(25, 0, "楷体");setbkmode(TRANSPARENT);settextcolor(YELLOW);outtextxy(10, 100, "西直门");*/
}bool showerror(string name)
{if (findStation(name) == -1){HWND abc = GetHWnd(); //获取窗口句柄SetWindowText(abc, "Caicai:出现错误"); //修改窗口标题 MessageBox(abc, "您输入的名称不存在或被停用", "PiedpiperG", MB_OKCANCEL); //设置对话框return true;}return false;
}void forbiddenstation(string name)
{int cur = findStation(name);Stations* sta = station[cur].nextStaion;while (sta){int nex = findRoad(station[cur].name, sta->name);road[nex].ifuse = false;sta = sta->nextStaion;}station[0].nextStaion = emptystation.nextStaion;station[cur].nextStaion = station[0].nextStaion;}void forbiddenroad(string name)
{for (int i = 1; i < Stationnum; i++){for (int j = 0; j < 20; j++){if (station[i].belongs[j] == name){forbiddenstation(station[i].name);break;}}}
}
run.cpp
#undef UNICODE
#undef _UNICODE
#include"function1.h"int main()
{readfile1();readfile2();initMap();//cout << findbelong("沙河", "昌平");//string start;//string end;/*print1();print2();*/HWND hwnd;hwnd = initgraph(1000, 750, SHOWCONSOLE);//创建一个窗口IMAGE background;//定义一个图片名.loadimage(&background, "./images/Bsubway.png", 1000, 750, 1);//从图片文件获取图像SetWindowText(hwnd, "PiedpiperG and Cai");int Mode = 0; //判断处于什么模式,默认值0为菜单模式char start[10] = {};char end[10] = {};char insertstart[10] = {};char insertend[10] = {};char insertlength[10] = {};char stopusesta[10] = {};char stopuselin[10] = {};while (1){BeginBatchDraw(); //缓冲区打印,防止闪屏cleardevice();//刷新putimage(0, 0, &background);//绘制图像到屏幕,图片左上角坐标为(0,0)while (_kbhit())//如果有按键则进入,否则不进入循环{char userkey = 0;userkey = _getch();if (userkey == VK_ESCAPE){Mode = 0;}}if (Mode == 0){TCHAR s[50] = "1.查找线路";TCHAR s1[50] = "2.关停站点";TCHAR s2[50] = "3.关停线路";TCHAR s3[50] = "4.插入路线";button(391, 200, 170, 50, s);button(391, 300, 170, 50, s1);button(391, 400, 170, 50, s2);button(391, 500, 170, 50, s3);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN:if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 200 && msg.y <= 200 + 50){cout << "!" << endl;Mode = 1;//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 300 && msg.y <= 300 + 50){cout << "?" << endl;Mode = 2;//在此处写下按钮点击时要执行的函数,实现相应的功能 }if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 400 && msg.y <= 400 + 50){cout << "@" << endl;Mode = 3;//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 170 && msg.y >= 500 && msg.y <= 500 + 50){cout << "&" << endl;Mode = 4;//在此处写下按钮点击时要执行的函数,实现相应的功能}break;default:break;}}}else if (Mode == 1){TCHAR s[50] = "请输入起点";TCHAR s1[50] = "请输入终点";TCHAR s2[50] = "确认";button(391, 200, 250, 50, s);button(391, 300, 250, 50, s1);button(391, 400, 250, 50, s2);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 200 && msg.y <= 200 + 50){cout << "输入起点" << endl;InputBox(start, 100, "请输入起点");if (showerror(start)){start[0] = '\0';}//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 300 && msg.y <= 300 + 50){cout << "输入终点" << endl;InputBox(end, 100, "请输入终点");if (showerror(end)){end[0] = '\0';}//在此处写下按钮点击时要执行的函数,实现相应的功能 }if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 400 && msg.y <= 400 + 50){cout << "确认" << endl;string s = start;string e = end;dijkstra(s, e);dijkstra2(s, e);dijkstra3(s, e);Mode = 9;//在此处写下按钮点击时要执行的函数,实现相应的功能 }break;default:break;}}setbkmode(TRANSPARENT);settextcolor(LIGHTBLUE);outtextxy(751, 200, start);outtextxy(751, 300, end);}else if (Mode == 9){//cout << "9" << endl;display();TCHAR s[50] = "下一页";button(700, 700, 100, 25, s);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 700 && msg.x <= 700 + 75 && msg.y >= 700 && msg.y <= 700 + 25){cout << "下一页" << endl;Mode = 10;//在此处写下按钮点击时要执行的函数,实现相应的功能}break;default:break;}}}else if (Mode == 10){display2();TCHAR s[50] = "上一页";button(600, 700, 100, 25, s);TCHAR s1[50] = "下一页";button(700, 700, 100, 25, s1);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 600 && msg.x <= 600 + 75 && msg.y >= 700 && msg.y <= 700 + 25){cout << "上一页" << endl;Mode = 9;//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 700 && msg.x <= 700 + 75 && msg.y >= 700 && msg.y <= 700 + 25){cout << "下一页" << endl;Mode = 11;//在此处写下按钮点击时要执行的函数,实现相应的功能}break;default:break;}}}else if (Mode == 11){display3();TCHAR s[50] = "上一页";button(600, 700, 100, 25, s);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 600 && msg.x <= 600 + 75 && msg.y >= 700 && msg.y <= 700 + 25){cout << "上一页" << endl;Mode = 10;//在此处写下按钮点击时要执行的函数,实现相应的功能}break;default:break;}}}else if (Mode == 2){TCHAR s[50] = "输入想要停用的站点";TCHAR s2[50] = "确认";button(391, 200, 280, 50, s);button(391, 400, 280, 50, s2);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 200 && msg.y <= 200 + 50){cout << "输入想要停用的站点" << endl;InputBox(stopusesta, 100, "输入想要停用的站点");if (showerror(stopusesta))stopusesta[0] = '\0';//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 400 && msg.y <= 400 + 50){cout << "确认2" << endl;string s = stopusesta;forbiddenstation(s);HWND abc = GetHWnd(); //获取窗口句柄SetWindowText(abc, "Caicai:操作成功"); //修改窗口标题 MessageBox(abc, "站点已被关闭", "PiedpiperG", MB_OKCANCEL); //设置对话框//在此处写下按钮点击时要执行的函数,实现相应的功能 }break;default:break;}}setbkmode(TRANSPARENT);settextcolor(LIGHTBLUE);outtextxy(751, 200, stopusesta);}else if (Mode == 3){TCHAR s[50] = "输入想要停用的线路";TCHAR s2[50] = "确认";button(391, 200, 280, 50, s);button(391, 400, 280, 50, s2);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 200 && msg.y <= 200 + 50){cout << "输入想要停用的线路" << endl;InputBox(stopuselin, 100, "线路前+#如#1号线");//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 400 && msg.y <= 400 + 50){cout << "确认2" << endl;string s = stopuselin;forbiddenroad(s);HWND abc = GetHWnd(); //获取窗口句柄SetWindowText(abc, "Caicai:操作成功"); //修改窗口标题 MessageBox(abc, "线路已被关闭", "PiedpiperG", MB_OKCANCEL); //设置对话框//在此处写下按钮点击时要执行的函数,实现相应的功能 }break;default:break;}}setbkmode(TRANSPARENT);settextcolor(LIGHTBLUE);outtextxy(751, 200, stopuselin);}else if (Mode == 4){TCHAR s[50] = "请输入起点";TCHAR s1[50] = "请输入终点";TCHAR s2[50] = "确认";TCHAR s3[50] = "请输入距离";button(391, 200, 250, 50, s);button(391, 300, 250, 50, s1);button(391, 500, 250, 50, s2);button(391, 400, 250, 50, s3);ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN://cout << "!!!!!!!" << endl;if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 200 && msg.y <= 200 + 50){cout << "输入起点" << endl;InputBox(insertstart, 100, "请输入起点");cout << insertstart << endl;if (showerror(insertstart)){start[0] = '\0';}//在此处写下按钮点击时要执行的函数,实现相应的功能}if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 300 && msg.y <= 300 + 50){cout << "输入终点" << endl;InputBox(insertend, 100, "请输入终点");cout << insertend << endl;//在此处写下按钮点击时要执行的函数,实现相应的功能 }if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 500 && msg.y <= 500 + 50){cout << "确认" << endl;string s = insertstart;string e = insertend;insertroad(insertstart, insertend, insertlength);HWND abc = GetHWnd(); //获取窗口句柄SetWindowText(abc, "Caicai:操作成功"); //修改窗口标题 MessageBox(abc, "成功插入线路", "PiedpiperG", MB_OKCANCEL); //设置对话框//在此处写下按钮点击时要执行的函数,实现相应的功能 }if (msg.x >= 391 && msg.x <= 391 + 250 && msg.y >= 400 && msg.y <= 400 + 50){cout << "输入距离" << endl;InputBox(insertlength, 100, "请输入距离");//在此处写下按钮点击时要执行的函数,实现相应的功能 }break;default:break;}}setbkmode(TRANSPARENT);settextcolor(LIGHTBLUE);outtextxy(751, 200, insertstart);outtextxy(751, 300, insertend);outtextxy(751, 400, insertlength);}EndBatchDraw();//缓冲区打印}closegraph();//关闭窗口}
地铁线路查询(easyx)相关推荐
- 石家庄地铁线路查询系统
石家庄地铁线路查询系统开发: 合作人:张旺 数据库的设计为:建立了一张表,有line_id(路线号).stop_id(站号).stop_name(站名).change(某站可换乘的线号)这几列. st ...
- Java、JSP地铁线路查询系统
技术:Java.JSP等 摘要: 南京市地铁线路查询系统是城市道路交通的重要组成部分,是城市发展的必然产物,是联系国民生活.社会生产和流通领域的关键环节.南京市地铁线路查询系统的发展一直处于一个较落后 ...
- 苏州地铁线路查询接口 地铁线路实时详细信息
苏州地铁线路查询接口将返回具体地铁线路实时详细信息,包括列车站台编号.位置描述.站台名称.列车编号.列车首班车.列车末班车.纬度.经度.距离当前位置.是否靠近地铁口.列车到站情况等等,调用非常方便. ...
- 地铁线路查询系统的设计与实现
技术:Java.JSP等 摘要: 南京市地铁线路查询系统是城市道路交通的重要组成部分,是城市发展的必然产物,是联系国民生活.社会生产和流通领域的关键环节.南京市地铁线路查询系统的发展一直处于一个较落后 ...
- 基于C++实现广州地铁线路查询【100010817】
广州地铁线路查询 一.实验目的 百度地图.高德地图等软件在导航时,如果选择出行方式为地铁,通常将提供从起点站到终点站的最短路径或者是多条规划路径的具体线路名称.本次实验旨在实现一个以广州地铁为基础数据 ...
- 公交地铁线路查询系统(app)
说明 本项目前后端分离,采用的是b/s结构,写论文的时候可以把b/s的优点与传统C/S结构的缺点相比较,这样好些 论文里面也可以把传统app隐私等等缺点与webapp的有点拿出来比较 后端 ...
- c++实现北京地铁线路查询系统
//使用前将bgstations.txt(文件的内容在代码末尾)放在与cpp文件的同一位置 #include<stdio.h> #include<string.h> #incl ...
- 利用百度地图查询全国地铁线路
最近做了个项目,该项目可以方便查询全国地铁线路,地铁线路上模拟小车到站提醒,点击小车可触发相关事件,使用的有 百度地图查询地铁线路 ,地铁图api,再结合vue-baidu-map 1.判断地铁线路图 ...
- python地铁查询系统_基于图结构实现地铁乘坐线路查询
基于图结构实现地铁乘坐线路查询 github-python算法和flaskapp部分:repo github-android部分:repo flaskapp接口文档:传送门 深度了解Dijkstra优 ...
- 基于图结构实现地铁乘坐线路查询
基于图结构实现地铁乘坐线路查询 github-python算法和flaskapp部分:repo github-android部分:repo flaskapp接口文档:传送门 深度了解Dijkstra优 ...
最新文章
- Android开发之发送邮件功能的实现(源代码分享)
- nginx proxy_next_upstream导致的一个重复提交错误
- 《PHP综合开发环境》(NuSphere PhpED v5.6.5615 Win32)[压缩包]
- 重装上阵怎么造简便机器人_重装上阵怎么造厉害的机器人?新人必看的干货组装教学[多图]...
- 【9018:1956】线段树1
- 小团队前端部署演化之路
- MVC与三层架构区别
- 10.cadence.自定义焊盘的创建[原创]
- 高级版本VS打开低版本VS工程,无法调试的问题
- python如何搭建环境_Python基础环境如何搭建
- 电子科技大学研究生图论课程
- 徐思201771010132《面向对象程序设计(Java)》第十二周学习总结
- window.open 卡死
- 江西省中小学生学籍管理-登录(1)
- C语言·XDOJ练习·拼数字
- cmd 一键清除系统垃圾
- Excel 中连续生成开始日期和结束日期之间的日期
- 集成学习(voting)
- 教会你怎么安装和使用 Visio 哦 ~ ~
- 转载 如何用示波器进行UART串口数据分析
热门文章
- html记忆游戏,html5 最强大脑最强记忆游戏
- Windows设置电脑每天自动重启
- 关键字private、static总结
- nginx在Linux系统安装
- inurl home.php,phpweb /version.php Vul
- JAVA、android常用时间处理方法及类似微信微博发表时间显示
- 为选区添加描边_ps怎么给选区加上虚线描边
- acm 算法 java_【经验总结】Java在ACM算法竞赛编程中易错点
- python ttk separator_Python GUI编程(Tkinter)
- 【万人围观】20位著名作家,100句惊艳了时光的名句