补发一下老东西(未优化)
目录
设计具体内容:
应用相关数据结构及算法,设计并实现一个具有查询功能的城市公交查询系统。设计其信息数据结构,实现如下功能:
(1)有 2 种或 2 种以上的查询功能选择等;
(2)实现根据公交路线查询出该路公交的全部途经路线,根据站点实现途经该站点的公交线路;
(3)能够实现换乘查询功能,或2 点之间有无公车通过的线路;
(4)实现可以规避某一二个站点的最优线路(良好);
(5)根据手机或者其他设备提供的功能,设计步行、骑行、公交或者驾车等的二个选项,并设计出以最短时间、最短路径优先的推荐路径方案中的二个选项,能根据最优排序结果输出全部公交线路和站点的信息等(优秀)
要求:
(1)理解及熟练运用相关图路径算法;
(2)理解运用运用图的存储;
(3)理解运用相关查询技术;
(4)界面友好、系统运行应该快速、稳定、高效和可靠。
功能模块图:
各模块流程图:
运行效果图:
源码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <stack>
using namespace std;
//邻接矩阵的存储结构
typedef struct Cell
{
int adj[100]; //存储权值
//记录每个站点所经过的公交线路数,在程序中用作标记量
int adj_loc;
}cell[500][500];
//无向带权图的存储结构
typedef struct map
{
string vex[500]={"徐工院","汉源国际华城","丽水路","龙湖之家西门","徐州市档案馆","绿地商务城","海顿广场","公园首府","元和路","汉风路","普陀路","彭祖大道"};
//顶点字符串数组
cell arcs; //邻接矩阵
int vexnum,arcnum; //顶点数量和边的数量
}graph;
graph G;
int road[50] = {1,2,3};//记录公交路线号
int road_a =3;//记录公交路线数
//判断顶点是否重复
int vex_repeat(string &point)
{
int i = 0;
for(i = 0;i<500;i++)
{
if(point == G.vex[i]) //vex顶点
return 0;
}
return 1;
}
//确定某个顶点 v 在图 G 中的位置
int Locate_vex(string v)
{
int i;
for(i = 0;i < 500;i++)
{
if(G.vex[i] == v)//string定义中的汉字可以直接比较是否相等
return i;
}
return -1;
}
//输出图G的顶点
void print_vex()//显示站点
{
int num;
for(num = 0;num < G.vexnum;num++)
{
cout<<num<<":"<<G.vex[num]<<endl;
}
}
//输出图G的邻接矩阵
void print_arcs()//显示站点间的公交路线
{
int num1,num2,num3;
for(num1 = 0;num1 < G.vexnum;num1++)
{
cout<<"站点"<<num1<<":";
for(num2 = 0;num2 < G.vexnum;num2++)
{
cout<<"(";
for(num3 = 0;num3 < G.arcs[num1][num2].adj_loc;num3++)
{
cout<<G.arcs[num1][num2].adj[num3]<<",";
}
cout<<")"<<"\t";
}
cout<<"*"<<endl;
}
}
/*起始点*/
//建立顶点的存储结构
void Create_vex()
{
for(int k = 12;k < 500;k++)
{
G.vex[k] = "0";
}
G.vexnum = 12;
}
//建立邻接矩阵的存储结构
void Creat_arcs()
{
int sum_arcs = 0; //记录边的总数
//对邻接矩阵进行初始化
for(int i = 0;i<500;i++)
{
for(int j = 0;j < 500;j++)
{
G.arcs[i][j].adj_loc = 0;
for(int c = 0;c < 100;c++)
{
G.arcs[i][j].adj[c] = 0;
}
}
}
//1号线
G.arcs[1][2].adj[G.arcs[1][2].adj_loc++] = 1;
G.arcs[2][3].adj[G.arcs[2][3].adj_loc++] = 1;
G.arcs[3][4].adj[G.arcs[3][4].adj_loc++] = 1;
G.arcs[4][5].adj[G.arcs[4][5].adj_loc++] = 1;
G.arcs[5][6].adj[G.arcs[5][6].adj_loc++] = 1;
G.arcs[6][5].adj[G.arcs[6][5].adj_loc++] = 1;
G.arcs[5][4].adj[G.arcs[5][4].adj_loc++] = 1;
G.arcs[4][3].adj[G.arcs[4][3].adj_loc++] = 1;
G.arcs[3][2].adj[G.arcs[3][2].adj_loc++] = 1;
G.arcs[2][1].adj[G.arcs[2][1].adj_loc++] = 1;
//2号线
G.arcs[1][7].adj[G.arcs[1][7].adj_loc++] = 2;
G.arcs[7][3].adj[G.arcs[7][3].adj_loc++] = 2;
G.arcs[3][4].adj[G.arcs[3][4].adj_loc++] = 2;
G.arcs[4][10].adj[G.arcs[4][10].adj_loc++] = 2;
G.arcs[10][11].adj[G.arcs[10][11].adj_loc++] = 2;
G.arcs[11][10].adj[G.arcs[11][10].adj_loc++] = 2;
G.arcs[10][4].adj[G.arcs[10][4].adj_loc++] = 2;
G.arcs[4][3].adj[G.arcs[4][3].adj_loc++] = 2;
G.arcs[3][7].adj[G.arcs[3][7].adj_loc++] = 2;
G.arcs[7][1].adj[G.arcs[7][1].adj_loc++] = 2;
//3号线
G.arcs[0][6].adj[G.arcs[0][6].adj_loc++] = 3;
G.arcs[6][8].adj[G.arcs[6][8].adj_loc++] = 3;
G.arcs[8][10].adj[G.arcs[8][10].adj_loc++] = 3;
G.arcs[10][1].adj[G.arcs[10][1].adj_loc++] = 3;
G.arcs[1][10].adj[G.arcs[1][10].adj_loc++] = 3;
G.arcs[10][8].adj[G.arcs[10][8].adj_loc++] = 3;
G.arcs[8][6].adj[G.arcs[8][6].adj_loc++] = 3;
G.arcs[6][0].adj[G.arcs[6][0].adj_loc++] = 3;
G.arcnum =14;
}
//建立图的存储结构
void Creat_graph()
{
Create_vex();
Creat_arcs();
}
//判断公交号是否已存在
int Locate_road(int j)
{
for(int i=0;i<road_a;i++)
{
if(road[i]==j)return 1;
}
return -1;
}
//用户手动录入新的站点
void add_vex()//手动输入站点
{
string str,str1,str2;
int num,j;
int loca1,loca2,loca;
while(1)
{
cout<<"请您输入需要增加的新的站点:"<<endl;
cin>>str;
loca = Locate_vex(str);
if(loca!=-1)
{
cout<<"该站点已存在,请重新输入"<<endl;
continue;
}
else break;
}
cout<<"请您输入该站点属于几路公交车"<<endl;
cin>>num;
j=Locate_road(num);
if(j==-1)//新加路线号,更新全局变量
{
road[road_a]=num;
num++;
}
while(1)
{
cout<<"请您输入该站点的前一站是:"<<endl;
cin>>str1;
loca1 = Locate_vex(str1);
if(loca1==-1)
{
cout<<"该站点不存在,请重新输入"<<endl;
continue;
}
cout<<"请您输入该站点的后一站是:"<<endl;
cin>>str2;
loca2 = Locate_vex(str2);
if(loca2==-1)
{
cout<<"该站点不存在,请重新输入"<<endl;
continue;
}
if(loca2!=-1&&loca1!=-1)break;
}
G.vex[G.vexnum] = str; //将该站点的信息增加到vex的数组中
loca1 = Locate_vex(str1);
loca2 = Locate_vex(str2); //定位str1和str2的位置
//对新增线路增加权值
G.arcs[loca1][G.vexnum].adj[G.arcs[loca1][G.vexnum].adj_loc++] = num;
G.arcs[G.vexnum][loca1].adj[G.arcs[G.vexnum][loca1].adj_loc++] = num;
G.arcs[loca2][G.vexnum].adj[G.arcs[loca2][G.vexnum].adj_loc++] = num;
G.arcs[G.vexnum][loca2].adj[G.arcs[G.vexnum][loca2].adj_loc++] = num;
G.vexnum++; //站的数量增加
cout<<"该站点录入成功!"<<endl;
}
//删除现存的站点
void dele_vex()
{
string str;
int locale = -1;
cout<<"请您输入要删除的站点名称:"<<endl;
cin>>str;
locale = Locate_vex(str);
if(locale == -1)
{
cout<<"删除现存站点失败!"<<endl<<"该站点不存在!"<<endl;
}
if(locale != 0)
{
G.vex[locale] = "0"; //将该站点名称清空
for(int i = 0;i < G.vexnum;i++)
{
for(int j = 0;j < 100;j++)
{
G.arcs[locale][i].adj[j] = 0;
G.arcs[i][locale].adj[j] = 0; //将存储站点权值的数组清空
}
G.arcs[locale][i].adj_loc = 0;
G.arcs[i][locale].adj_loc = 0; //将表示该站点的权值数量的变量清零
}
//G.vexnum--;
cout<<"删除站点成功!"<<endl;
}
}
void modify_vex()//修改站点名称
{
string str;
string str1;
int loca = -1;
cout<<"请输入您要修改的站点名称 : "<<endl;
cin>>str;
loca = Locate_vex(str);
if(loca == -1)
{
cout<<"修改站点失败! "<<"该站点不存在! "<<endl;
}
if(loca != -1)
{
cout<<"请输入修改后的名称:"<<endl;
cin>>str1;
G.vex[loca] = str1;
cout<<"站点修改成功!"<<endl;
}
}
void add_line()//用户手动增加新的公交线路
{
string st1,st2;
int linenum;
int locate1,locate2;
cout<<"请您输入要在哪两个站点之间增加线路:"<<endl;
cout<<"请您先输入第一个站点"<<endl;
cin>>st1;
cout<<"请您再输入第二个站点"<<endl;
cin>>st2;
cout<<"请您输入要增加的线路号数:"<<endl;
cin>>linenum;
locate1 = Locate_vex(st1);
locate2 = Locate_vex(st2);
G.arcs[locate1][locate2].adj[G.arcs[locate1][locate2].adj_loc++] = linenum;
G.arcs[locate2][locate1].adj[G.arcs[locate2][locate1].adj_loc++] = linenum;
cout<<"该站点录入成功!"<<endl;
}
//调整站点间的线路号
int modify_adj()
{
string str1,str2;
int lint1,lint2;
int line1,line2;
cout<<"请输入想要修改线路号的站点"<<endl;
cout<<"请输入第一个站点:"<<endl;
cin>>str1;
cout<<"请输入第二个站点:"<<endl;
cin>>str2;
lint1 = Locate_vex(str1);
lint2 = Locate_vex(str2); //找到这两个站点在矩阵中的位置
cout<<"该站点间已经存在的线路号是:";
int flag = 0; //作为标记,检查这两站之间是否有线路相通
int i = 0,j = 0;
for(int i = 0;i < G.arcs[lint1][lint2].adj_loc;i++)
//输出两站点间已经存在的线路号
{
cout<<G.arcs[lint1][lint2].adj[i]<<"号 ";
flag = 1;
}
if(flag == 0)
{
cout<<"您输入的两站之间不存在线路,请您手动增加线路"<<endl;
return 0;
}
cout<<endl;
cout<<"请输入想要改动的站点间的线路号"<<endl;
cin>>line1;
cout<<"请输入修改后的线路号"<<endl;
cin>>line2;
for(int j = 0;j < G.arcs[lint1][lint2].adj_loc;j++)
{
if(G.arcs[lint1][lint2].adj[j] == line1)
{
G.arcs[lint1][lint2].adj[i] = line2;
G.arcs[lint2][lint1].adj[i] = line2;
cout<<"站点的线路号修改成功!"<<endl;
break;
}
}
if(j == G.arcs[lint1][lint2].adj_loc)
cout<<"您的输入有误!"<<endl;
return 1;
}
//对图进行运用迪杰斯特拉算法完成换乘搜索
//全局变量的定义
#define INFMAX 500 //路程最大值
bool visit[500]; //标志站点有没有被访问过
string un_vex ; //规避站点
struct load{
int vex[500]; //站点顺序
int vex_loc; //站点的总数
}P[500]; //换乘站点记录
int D[500]; //所在站点到其他站点的最短路程
//建立链表结构存储一条线上的顶点完成直达检索
bool direct_path()
{
string str[road_a][G.vexnum];
for(int k=0;k<road_a;k++)//
{
int a=0;
for(int i = 0;i<G.vexnum;i++)
{
for(int j = 0;j<i;j++)
{
for(int c=0;c<G.arcs[i][j].adj_loc;c++)
{
if(G.arcs[i][j].adj[c]==road[k])
{
if(a==0&&i<=j){str[k][a]=G.vex[i];cout<<str[k][a]<<",";a++;}
else if(a==0&&i>j){str[k][a]=G.vex[j];cout<<str[k][a]<<",";a++;}
for(int h=0;h<a;h++)
{
if(G.vex[i]==str[k][h]){str[k][a]=G.vex[j];cout<<str[k][a];a++;break;}
if(G.vex[j]==str[k][h]){str[k][a]=G.vex[i];cout<<str[k][a];a++;break;}
}
cout<<str[k][a]<<",";
}
}
}
}
cout<<endl;
str[k][a]="0";
}
int i = 0;
int j = 0;
string str1;
string str2; //起始站
string str3; //终点站
int loca1,loca2,loca3,loca4,temp;
bool flag1,flag2;
bool flag = false;
cout<<"-------最优路线选择------"<<endl;
cout<<"请输入您的起始站:";
cin>>str2;
cout<<"请输入您的终点站:";
cin>>str3;
cout<<"请输入您需要规避的站点(如果没有请输入'无'):";
cin>>un_vex;
//查找直达线路并作记录
for(i = 0;i < road_a;i++)
{
flag1 = false;
flag2 = false;
for(j = 0;j < G.vexnum; j++)
{
if(str2 == str[i][j]&&str2!=un_vex)
{
loca1 = i;
loca2 = j;
flag1 = true;
}
if(str3 == str[i][j]&&str2!=un_vex)
{
loca3 = i;
loca4 = j;
flag2 = true;
}
}
if((flag1 == true)&&(flag2 == true))//表示直达线路查找成功
{
flag = true;
cout<<"该两站点之间存在直达线路"<<endl;
cout<<"该线路号为 "<<i+1<<" 号公交线路"<<endl;
}
}
if(flag == false)
cout<<"该两站点之间没有直达路线! 即将为您显示换乘公交路线!"<<endl;
return flag; //若falg = false,表示没有直达路线
}
//最优换乘路线(迪杰斯特拉算法)
void djc(int v0)
{
int v,w;
int un_loc=Locate_vex(un_vex); //需要规避站点的位置
for(v = 0;v < G.vexnum;v++)
{
if(v == un_loc) visit[v]=true; //对visit数组初始化(标记数组)
else visit[v] = false;
if(G.arcs[v0][v].adj_loc <= 0) D[v] = INFMAX; //对D数组初始化 (最短路程记录数组)
else D[v] = 1;
for(w = 0;w < G.vexnum;w++) P[v].vex_loc = 0; //对P数组初始化(换乘记录数组)
if(D[v] < INFMAX) {P[v].vex[++P[v].vex_loc] = v0;P[v].vex[++P[v].vex_loc] = v;}
}
D[v0] = 0;visit[v0] = true; //v0为起点
int i,min; //min为到达未访问站点的最短路程
for(i = 1;i < G.vexnum;i++) //计算起始站到所有站点的最短路径
{
min = INFMAX;
for(w = 0;w < G.vexnum;w++)
{
if(!visit[w])
if(D[w] < min) {v = w;min = D[w];}
}
visit[v] = true;
for(w = 0;w < G.vexnum;w++)
{
if(!visit[w]&&G.arcs[v][w].adj_loc > 0&&min+1 < D[w] )
{
D[w]=D[v]+1;
P[w]=P[v];
P[w].vex[++P[w].vex_loc] = w;
}
}
}
}
//换乘车的线路
void Indirect_path()
{
int i,j;
int loc1,loc2;
string str1,str2;
cout<<"换乘公交路线显示:"<<endl;
cout<<"请输入起始站点: ";
cin>>str1;
cout<<"请输入终点站: ";
cin>>str2;
loc1 = Locate_vex(str1);
loc2 = Locate_vex(str2);
djc(loc1);
for(i = 2;i <= P[loc2].vex_loc;i++)
{
cout<<"前往站点"<<G.vex[P[loc2].vex[i]];
cout<<" 公交路线号为"<<G.arcs[P[loc2].vex[i-1]][P[loc2].vex[i]].adj[0]<<"号公交路线"<<endl;
}
cout<<endl;
}
int main()
{
int choose;
bool choose_flag; //bool型变量只有true或false两个值
Creat_graph();
while(1)
{
cout<<" &欢迎使用公交查询系统& "<<endl;
cout<<"********************************************"<<endl;
cout<<"* 1.显示所有站点信息 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 2.显示站点之间的公交路线号 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 3.新增站点信息 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 4.删除站点信息 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 5.修改站点名称 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 6.手动增加公交路线 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 7.调整站点间的线路 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 8.搜索两站之间的路线 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 9.退出程序 *"<<endl;
cout<<"*------------------------------------------*"<<endl;
cout<<"* 请选择 *"<<endl;
cout<<"********************************************"<<endl;
cin>>choose;
switch(choose)
{
case 1:print_vex();break;
case 2:print_arcs();break;
case 3:add_vex();break;
case 4:dele_vex();break;
case 5:modify_vex();break;
case 6:add_line();break;
case 7:modify_adj();break;
case 8:
{
choose_flag = direct_path();
if(choose_flag == false)Indirect_path();
else break;
}
case 9:
{
cout<<"退出程序"; exit(1);
}
default:cout<<"您的选择有误!"<<endl;
}
system("pause");//程序暂停
system("cls"); //清屏
}
return 0;
}