首页 » 软件开发 » 包含源代码和注释,任务和报告(线路图公交站点数据结构注释)

包含源代码和注释,任务和报告(线路图公交站点数据结构注释)

雨夜梧桐 2024-07-24 13:26:02 0

扫一扫用手机浏览

文章目录 [+]

【题目】公交线路图

1、数据格式

用了四个txt文件:

包含源代码和注释,任务和报告(线路图公交站点数据结构注释) 软件开发
(图片来自网络侵删)

第一个:BUSES.txt

第一列为公交线路的名称,第二列为起点,第三列为终点。

比如第一行代表

一路上行公交从余店路开往中百超市

第二个:

STATIONS.txt

记录如图的站点信息。

第三个:

ROUTES.txt

记录路线信息,分别为

线路编号 站点编号 站点编号 距离

01 500意思是一路上行,从余店路开往中山公园,距离为500第四个:MAPNUM.txt

分别记录 BUSES,STATIONS, ROUTES的大小2、数据结构(读文件创建图)通过函数load_data()把文件里的数据读到全局变量数组中int load_data(){FILE f1;FILE f2;FILE f3;FILE f4;f1 =fopen("D:\\MyWorkSpace\\c\\公交线路图\\ROUTES.txt","r");f2 =fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","r");f3 =fopen("D:\\MyWorkSpace\\c\\公交线路图\\STATIONS.txt","r");f4 =fopen("D:\\MyWorkSpace\\c\\公交线路图\\MAPNUM.txt","r");if(f1==NULL){printf("load ROUTES.txt errer!\n");exit(0);}else if(f2==NULL){printf("load BUSES.txt errer!\n");exit(0);}else if(f3==NULL){printf("load STATIONS.txt errer!\n");exit(0);}else if(f4==NULL){printf("load MAPNUM.txt errer!\n");exit(0);}else{fscanf(f4,"%d%d%d",&BUS_NUM,&STATION_NUM,&ROUTE_NUM);fclose(f4);ROUTES= malloc(sizeof(int)ROUTE_NUM 4);BUSES= malloc(sizeof(char)BUS_NUM 3);STATIONS= (char)malloc(sizeof(char)STATION_NUM);int i;for(i=0;i<ROUTE_NUM;i++){fscanf(f1,"%d%d%d%d",&ROUTES[i][0],&ROUTES[i][1],&ROUTES[i][2],&ROUTES[i][3]);}for(i=0;i<BUS_NUM;i++){BUSES[i][0]= (char)malloc(20sizeof(char));BUSES[i][1]= (char)malloc(20sizeof(char));BUSES[i][2]= (char)malloc(20sizeof(char));fscanf(f2,"%s%s%s",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}for(i=0;i<STATION_NUM;i++){STATIONS[i]= (char)malloc(20sizeof(char));fscanf(f3,"%s",STATIONS[i]);}}fclose(f1);fclose(f2);fclose(f3);return 0;}采用邻接表储存公交线路图:通过void LoadMapDate()函数把数组的数据载入全局变量g_sMap中。
typedef struct Bus{char name; //公交线路名int start; //起点int end; //终点int stations; //公交线路站点索引数组int station_num;//站点个数}Bus;//2、定义结构体STATION代表一个站点typedef struct Station{char station; //站点名struct Route routes; //从该站点出发的所有下行路线的链域}Station;//3、定义结构体ROUTE代表公交线路中的一个路段(邻接表结点)typedef struct Route{int station; //指向的站点索引号int bus; //公交索引号int distance; //两点之间公路的距离bool visited; //遍历时的标识符struct Route next; //起始站点相同的,下一条下行路线}Route;//4、定义结构体BUSMAP存储整个公交地图信息typedef struct BusMap{Bus buses; //公交线路数组Station stations; //站点数组int station_num; //站点数int bus_num; //公交线路数}BusMap;BusMap g_sMap; //定义全局变量3、查询公交线路和站点信息(1) 查询公交线路通过QueryBus函数查询int QueryBus(char pBus,char stations){int sum=2; //记录站点个数,起点和终点没算//1、查找公交int flagBus=FindBus(pBus); //找到公交线路的索引//2、找到公交及信息char nStart=BUSES[flagBus][1];char nEnd=BUSES[flagBus][2];//3、输出起始站点printf("[%s线路]\t从[%s]开往[%s]\n",pBus,nStart,nEnd);//4、输出各站点int flagStart = FindStation(nStart); //找到起点的索引,从而找到后面路线int flagEnd = FindStation(nEnd);Station pStStation = &g_sMap.stations[flagStart];Route pStRoute = pStStation->routes;while(pStRoute->bus!=flagBus) //找到该公交线路的第一条路线{pStRoute=pStRoute->next;}printf("%s->",nStart); //输出起始站点while(pStRoute->station!=flagEnd) //如果路线不是最后一条路线{printf("%s->",(stations+(pStRoute->station)));sum++;pStStation = &g_sMap.stations[pStRoute->station]; //换到下一个路线的站点pStRoute = pStStation->routes; //下一个站点的第一条路线,不是该公交线路的第一条路线while(pStRoute->bus!=flagBus){pStRoute=pStRoute->next;}}printf("%s\n",nEnd);return sum;}运行结果为:

查询站点信息

函数代码如下:

//创建QueryStation函数,实现查询站点信息,输出该站点所经线路信息

int QueryStation(char pStation,char buses)

{

int flag[BUS_NUM];

int i;

for(i=0;i<BUS_NUM;i++)

{

flag[i]=-1;

}

int sum=0; //记录路线的总数

int flagStation=FindStation(pStation); //找到该站点的索引

Station pStStation=&g_sMap.stations[flagStation];

Route pStRoute=pStStation->routes;

int j=0;

while(pStRoute!=NULL)

{

flag[j]=pStRoute->bus;

j++;

pStRoute=pStRoute->next;

}

for(i=0;flag[i]!=-1;i++)

{

printf("%s\n",(buses+(flag[i])3));

//printf("%s\n",(buses+((flag[i])+1)3));

sum++;

}

return sum;

}

运行结果为:

4、查询两站点之间的路线,找到至多换乘1次的路线,并输出结果。

这个算法我是先写一个函数找到两个站点之间的直接路径,就是不换乘即可到达的路径。

通过bool directPath(char pStart,char pEnd,int direct_bus)函数判断两个站点之间是否有不换乘的直接路径,并且把两点之间的直接路径公交放在直达direct_bus数组里。

找换乘的路线,首先找到换乘的站点,通过遍历除了起点和终点的站点,调用directPath()函数,每个站点到起点有一个直达数组,每个站点到终点也有一个直达数组,通过循环搭配,即可找出所有的换乘一次的路线

即函数void Show_directPath(char pStart,char pEnd,int nBus)

公交线路图为:

函数代码如下:

void Show_transferPath(char pStart,char pEnd)

{

int nStart = FindStation(pStart);

int nEnd = FindStation(pEnd);

int path_sum=0;

int i=0,j=0;

//先输出直达的路线

int pathdirect_bus[BUS_NUM];

for(i=0;i<BUS_NUM;i++)

{

pathdirect_bus[i]=-1;

}

bool is_pathdirect=directPath(pStart,pEnd,pathdirect_bus); //判断是否有直达,如果有,把直达公交放在数组中

if(is_pathdirect==true)

{

for(i=0;pathdirect_bus[i]!=-1;i++)

{

path_sum++;

printf("第%d条路线为:\n",path_sum);

Show_directPath(pStart,pEnd,pathdirect_bus[i]);

printf("\n\n");

}

}

//换乘一次的路线

int stations[STATION_NUM-2]; //记录每个站点的索引

i=0;

for(i=0;i<STATION_NUM;i++)

{

int station_flag = FindStation(STATIONS[i]);

if(station_flag!=nStart&&station_flag!=nEnd)

{

stations[j]=station_flag;

j++;

}

}

int Start_directbus[BUS_NUM];

int End_directbus[BUS_NUM];

i=0;

for(i=0;i<BUS_NUM;i++)

{

Start_directbus[i]=-1;

End_directbus[i]=-1;

}

i=0;j=0;

int m,n;

for(i=0;i<(STATION_NUM-2);i++)

{

//必须要给数组重置

for(j=0;j<BUS_NUM;j++)

{

Start_directbus[j]=-1;

End_directbus[j]=-1;

}

bool Start_middle = directPath(pStart,STATIONS[stations[i]],Start_directbus);

bool End_middle = directPath(STATIONS[stations[i]],pEnd,End_directbus);

if(Start_middle==true&&End_middle==true)

{

for(m=0;Start_directbus[m]!=-1;m++)

{

for(n=0;End_directbus[n]!=-1;n++)

{

if(Start_directbus[m]!=End_directbus[n])

{

path_sum++;

printf("第%d条路线为:\n",path_sum);

Show_directPath(pStart,STATIONS[stations[i]],Start_directbus[m]);

printf("(在此站换乘)\n");

Show_directPath(STATIONS[stations[i]],pEnd,End_directbus[n]);

printf("\n\n");

}

}

}

}

}

if(path_sum==0)

{

printf("没有符合要求的路线!
\n");

}

}

运行结果为:

修改公交线路和站点信息,保存文件通过函数modify把全局变量的数据修改,然后再写入文件中保存,最后调用load_data()函数和void LoadMapDate()函数把数组的数据再载入全局变量g_sMap中。
修改某一条线路时,要动态设置数组,删一条线路,ROUTES_NUM就应该减1,ROUTES文档再重新写入,如果删除的站点是某一条线路的起点和终点,还需要修改BUSES文档。
代码如下:int modify_data(){int ch;char name1[20],name2[20];int distance;int i;printf("1、修改站点名称\n");printf("2、修改线路距离\n");printf("3、删除某一公交站点\n");ch=getch()-48;switch(ch){case 1:printf("请输入要修改的站点原名称:");scanf("%s",name1);printf("请输入修改后的站点名称:");scanf("%s",name2);int flag = FindStation(name1);STATIONS[flag]=name2;//LoadMapDate(); //重新加载FILE f1=fopen("D:\\MyWorkSpace\\c\\公交线路图\\STATIONS.txt","w");if(f1==NULL){printf("open error!\n");exit(0);}for(i=0;i<STATION_NUM;i++){fprintf(f1,"%s ",STATIONS[i]);}fclose(f1);for(i=0;i<BUS_NUM;i++){//printf("%d\n",g_sMap.buses[i].start);if(flag==g_sMap.buses[i].start){if(i%2==0){BUSES[i][1]=name2;BUSES[i+1][2]=name2;}else{BUSES[i][1]=name2;BUSES[i-1][2]=name2;}}}f1=fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","w");if(f1==NULL){printf("open BUSES error!\n");exit(0);}else{for(i=0;i<BUS_NUM;i++){fprintf(f1,"%s %s %s\n",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}fclose(f1);}printf("\n修改成功!
\n");break;case 2:printf("请输入想要修改的(相邻)两个站点:\n");printf("站点一:");scanf("%s",name1);printf("站点二:");scanf("%s",name2);printf("请输入这两站之间的距离(单位:米):");scanf("%d",&distance);int flag1 = FindStation(name1);int flag2 = FindStation(name2);for(i=0;i<ROUTE_NUM;i++){if(ROUTES[i][1]==flag1){if(ROUTES[i][2]==flag2){ROUTES[i][3]=distance;}}else if(ROUTES[i][1]==flag2){if(ROUTES[i][2]==flag1){ROUTES[i][3]=distance;}}}LoadMapDate(); //重新加载FILE f2 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\ROUTES.txt","w");for(i=0;i<ROUTE_NUM;i++){fprintf(f2,"%d %d %d %d\n",ROUTES[i][0],ROUTES[i][1],ROUTES[i][2],ROUTES[i][3]);}fclose(f2);break;case 3:printf("请输入要删除哪条公交线路的哪个站点:\n");printf("请输入公交线路:");scanf("%s",name1);printf("请输入站点:");scanf("%s",name2);int flag3 = FindStation(name2); //站点索引int flag4 = FindBus(name1); //公交线路索引if(flag3==g_sMap.buses[flag4].start){if(flag4%2==0){int modify1=Find_ROUTES_1(flag4,flag3);int modstart = ROUTES[modify1][2]; //先记录更新的起点delete_ROUTES(modify1);load_data();int modify2=Find_ROUTES_2(flag4+1,flag3);delete_ROUTES(modify2);load_data();BUSES[flag4][1]=STATIONS[modstart];BUSES[flag4+1][2]=STATIONS[modstart];FILE f4 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","w");if(f4==NULL){printf("open BUSES error!\n");exit(0);}for(i=0;i<BUS_NUM;i++){fprintf(f4,"%s %s %s\n",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}fclose(f4);}else{int modify1=Find_ROUTES_1(flag4,flag3);int modstart = ROUTES[modify1][2];delete_ROUTES(modify1);load_data();int modify2=Find_ROUTES_2(flag4-1,flag3);delete_ROUTES(modify2);load_data();BUSES[flag4][1]=STATIONS[modstart];BUSES[flag4-1][2]=STATIONS[modstart];FILE f4 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","w");if(f4==NULL){printf("open BUSES error!\n");exit(0);}for(i=0;i<BUS_NUM;i++){fprintf(f4,"%s %s %s\n",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}fclose(f4);}load_data();}else if(flag3==g_sMap.buses[flag4].end){if(flag4%2==0){int modify1=Find_ROUTES_2(flag4,flag3);int modend = ROUTES[modify1][1]; //记录更新的终点//printf("路线索引=%d\n更新的终点索引=%d\n",modify1,modend);delete_ROUTES(modify1);load_data();int modify2=Find_ROUTES_1(flag4+1,flag3);delete_ROUTES(modify2);load_data();BUSES[flag4][2]=STATIONS[modend];BUSES[flag4+1][1]=STATIONS[modend];FILE f4 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","w");for(i=0;i<BUS_NUM;i++){fprintf(f4,"%s %s %s\n",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}fclose(f4);}else{int modify1=Find_ROUTES_2(flag4,flag3);int modend = ROUTES[modify1][1];delete_ROUTES(modify1);load_data();int modify2=Find_ROUTES_1(flag4-1,flag3);delete_ROUTES(modify2);load_data();BUSES[flag4][2]=STATIONS[modend];BUSES[flag4-1][1]=STATIONS[modend];FILE f4 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\BUSES.txt","w");for(i=0;i<BUS_NUM;i++){fprintf(f4,"%s %s %s\n",BUSES[i][0],BUSES[i][1],BUSES[i][2]);}fclose(f4);}}else{printf("请输入删除该站点所形成的新路线的距离是(单位:米):");scanf("%d",&distance);if(flag4 % 2!=0){flag4--;}if(flag4 % 2==0){FILE f3 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\ROUTES.txt","w");int modify=Find_ROUTES_2(flag4,flag3);ROUTES[modify][2]=ROUTES[modify+1][2];ROUTES[modify][3]=distance;for(i=0;i<ROUTE_NUM;i++){fprintf(f3,"%d %d %d %d\n",ROUTES[i][0],ROUTES[i][1],ROUTES[i][2],ROUTES[i][3]);}fclose(f3);delete_ROUTES(modify+1);load_data(); //把修改的文件再导入f3 = fopen("D:\\MyWorkSpace\\c\\公交线路图\\ROUTES.txt","w");modify = Find_ROUTES_2(flag4+1,flag3);ROUTES[modify][2]=ROUTES[modify+1][2];ROUTES[modify][3]=distance;for(i=0;i<ROUTE_NUM;i++){fprintf(f3,"%d %d %d %d\n",ROUTES[i][0],ROUTES[i][1],ROUTES[i][2],ROUTES[i][3]);}fclose(f3);delete_ROUTES(modify+1);load_data(); //把修改的文件再导入}}LoadMapDate();printf("\n删除成功!
\n");break;default:printf("输入错误,请重新输入!
\n");break;}load_data();LoadMapDate();return 0;}第一个功能修改前:例如:二路上行终点是火车站

进行修改:

修改后:

因为输入的是某一个线路的起始或者终止站点,那么BUSES文档也会修改,如果只是一个中间站点,则只修改STATIONS文档,数据具有关联性。
此时文档为:

又例如第三个功能,删除某一条公交线路的某一条路线例如删除二路上行的终点火车站。
那么此时BUSES文档和ROUTES文档都需要修改。
修改前二路上行的路线如下,终点是火车站。

修改时:

修改后,此时二路上行终点变为中百超市,结果如图:

而此时的文档情况为:二路上行和二路下行的终点起点都进行了修改ROUTES文档也进行了删除和修改因此减少了两条路线,二路上行减少一条,二路下行也减少一条,所以ROUTES数组大小从34变为32

设计总结

这个实验前前后后做了一个多星期,因为有些东西忘了,又翻书复习,公交线路图之前在学校做过简单的,但是没有存入文件这个功能,又在网上以及书上学习了一些读取文件和写进文件的方法,最后因为还要有修改数据的功能,所以对于之前定义的全局变量数组,数组大小不能定义为静态的,而是要采用动态的定义二维数组,再通过malloc进行动态分配空间,有一次在宏定义None时,把None定义为0了,结果后面测试的时候总是发生错误,后来发现当没找到路线时,赋值为None,而一路上行的索引也为0,就导致了冲突,后来把None改为-1就解决了问题,通过这次课设,更加了解了邻接表储存图的操作,还学会了文件读取和写入的操作,通过模块化,把主页面和功能分开,当时读写文件的时候,中文字符一直乱码,查了一下把txt文件的编码改了一下,总之乱码一般就是编码不一致导致的,不管遇到问题还是bug,其实自己都可以慢慢解决,就是时间问题,不能急躁,这次课设,从中受益匪浅。

标签:

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读3 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0