铁路交通咨询系统

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、基本功能
  • 二、具体实现
    • 1.初始化系统
    • 2.显示所有车次信息
    • 3.通过城市名称,查询两城市间最省钱的搭乘方式
    • 4.通过城市名称,寻找两个城市之间所有可以采用的搭乘方式
    • 5.输入城市名称,并根据当前时间,查询出最快发出的列车及乘坐信息.
  • 总结


前言

一个数据结构课程的小课设,主要用C语言搭配数据结构图的深度优先遍历,迪杰斯特拉,栈的运用等等。


一、基本功能

    至少提供十条以上的铁路线路,便于测试转乘线路、最小花费等功能。需要为用户提供一个友好的功能菜单,根据用户的实际需求,菜单中应至少包括(但不限于)以下几个基本功能:

  1. 初始化系统;(提供文本直接初始化和手动输入两种初始化方式)
  2. 显示所有车次信息;
  3. 查询车站信息,包括站名,途径该站点的车次相关信息等;
  4. 通过城市名称进行查询,输出两城市间最省钱的搭乘方式,如所花费的费用、经过的站点、转乘的相关信息(如在哪里转乘,搭乘列车信息)等;
  5. 通过城市名称,查询两城市间最省时间的搭乘方式;
  6. 通过城市名称,寻找两个城市之间所有可以采用的搭乘方式;
  7. 输入城市名称,并根据当前时间,查询出最快发出的列车及乘坐信息;
  8.  退出咨询系统;

二、具体实现

1.初始化系统

  系统的文本初始化运用到了c语言中的文件读取的操作,也方便输入数据和更改数据,但运用的也比较少,也是在网上学了才会的。

最好直接在编程所在文件下之间创建一个txt,再通过如下赋予txt的内容:

FILE* pf = fopen("tielu.txt", "r");

这里面的tielu.txt是我所创建的txt,r的意思是读取数据,还有w是写入数据,a是在末尾写入数据。

    if (pf != NULL) //如果pf不为空
    { 

        fscanf(pf,"&a");
        fclose(pf);
        pf = NULL;
    }

通过fscanf就可以使a读取pf的数据,也就是tielu.txt的数据,注意&的添加。如果文件读取后,打出来是乱码,就去改一下txt文档的格式,编码改为“ANSI”。

手动初始化也差不多,就是运用w。

#define MAX 100
#define OVER 9999

typedef struct time
{
	int hour;
	int minute;
}tmv; //列车的时间 

typedef struct {
	char name[MAX];
}city; // 城市名字 

typedef struct {
	int time;
	int cost;
	tmv starttime;
	tmv endtime;
	int checi;
} route; // 城市间的车次具体的信息 

typedef struct {
	int citycount;
	city cities[MAX];
	route routes[MAX][MAX];

} railysystem;  // 总的铁路管理系统的结构体 



void init(railysystem* system) { // 文本直接初始化 
	system->citycount = 8;

int i,j;
	for ( i = 0; i < system->citycount; i++) {
		for ( j = 0; j < system->citycount; j++) {
			system->routes[i][j].time = OVER;
			system->routes[i][j].cost = OVER;
			system->routes[i][j].starttime.hour = OVER;
			system->routes[i][j].starttime.minute = OVER;
			
		}
	}
 FILE* pf = fopen("tielu.txt", "r");
  
	if (pf != NULL)
	{
	
 
		fscanf(pf, "%s %s %s %s %s %s %s %s",system->cities[0].name,system->cities[1].name,system->cities[2].name,system->cities[3].name,system->cities[4].name,system->cities[5].name,system->cities[6].name,system->cities[7].name );
 fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[0][1].time,&system->routes[0][1].cost,&system->routes[0][1].starttime.hour,&system->routes[0][1].starttime.minute,&system->routes[0][1].endtime.hour,&system->routes[0][1].endtime.minute,&system->routes[0][1].checi);
 fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[0][7].time,&system->routes[0][7].cost,&system->routes[0][7].starttime.hour,&system->routes[0][7].starttime.minute,&system->routes[0][7].endtime.hour,&system->routes[0][7].endtime.minute,&system->routes[0][7].checi);		
  fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[1][4].time,&system->routes[1][4].cost,&system->routes[1][4].starttime.hour,&system->routes[1][4].starttime.minute,&system->routes[1][4].endtime.hour,&system->routes[1][4].endtime.minute,&system->routes[1][4].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[2][5].time,&system->routes[2][5].cost,&system->routes[2][5].starttime.hour,&system->routes[2][5].starttime.minute,&system->routes[2][5].endtime.hour,&system->routes[2][5].endtime.minute,&system->routes[2][5].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[3][5].time,&system->routes[3][5].cost,&system->routes[3][5].starttime.hour,&system->routes[3][5].starttime.minute,&system->routes[3][5].endtime.hour,&system->routes[3][5].endtime.minute,&system->routes[3][5].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[3][6].time,&system->routes[3][6].cost,&system->routes[3][6].starttime.hour,&system->routes[3][6].starttime.minute,&system->routes[3][6].endtime.hour,&system->routes[3][6].endtime.minute,&system->routes[3][6].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[4][3].time,&system->routes[4][3].cost,&system->routes[4][3].starttime.hour,&system->routes[4][3].starttime.minute,&system->routes[4][3].endtime.hour,&system->routes[4][3].endtime.minute,&system->routes[4][3].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[5][4].time,&system->routes[5][4].cost,&system->routes[5][4].starttime.hour,&system->routes[5][4].starttime.minute,&system->routes[5][4].endtime.hour,&system->routes[5][4].endtime.minute,&system->routes[5][4].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[6][1].time,&system->routes[6][1].cost,&system->routes[6][1].starttime.hour,&system->routes[6][1].starttime.minute,&system->routes[6][1].endtime.hour,&system->routes[6][1].endtime.minute,&system->routes[6][1].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[6][2].time,&system->routes[6][2].cost,&system->routes[6][2].starttime.hour,&system->routes[6][2].starttime.minute,&system->routes[6][2].endtime.hour,&system->routes[6][2].endtime.minute,&system->routes[6][2].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[7][4].time,&system->routes[7][4].cost,&system->routes[7][4].starttime.hour,&system->routes[7][4].starttime.minute,&system->routes[7][4].endtime.hour,&system->routes[7][4].endtime.minute,&system->routes[7][4].checi);
   fscanf(pf, "%d %d %d %d %d %d %d",&system->routes[7][6].time,&system->routes[7][6].cost,&system->routes[7][6].starttime.hour,&system->routes[7][6].starttime.minute,&system->routes[7][6].endtime.hour,&system->routes[7][6].endtime.minute,&system->routes[7][6].checi);
		fclose(pf);
		pf = NULL;
	}
	
	
}

2.显示所有车次信息

  通过图的深度优先遍历,以此达到将所有车次信息输出出来,遇到了如何将每个车次的信息保存并输出的问题,最后使用了栈的定义,通过每次的进栈来保存信息,最后在输出栈中的数据,来完成每一次车次信息。

int stack[MAX],y[MAX]={0},top=0; //为DFS作为标记和栈 
int h=0;

void DFS(railysystem *system,int x,int z,int p){ //通过DFS1来寻找所有的车次信息 
	int i;
	 
	if(x==z){ //当st=et,代表已经找到了两个城市间的路径,可以打印 
	    stack[top++] = z; //把终点城市放进去 
			h++;
	    
	    printf("车次%d:\n",h);
		printf("始发站:%s 终点站:%s\n",system->cities[p].name,system->cities[z].name);
		for(i=0;i<top-1;i++)
		{
	
			int b = ++i;
			i--;
			
			printf("车次号:%d %s->%s \n",system->routes[stack[i]][stack[b]].checi,system->cities[stack[i]],system->cities[stack[b]]);
            printf("出发时间:%d:%02d 到站时间:%d:%02d 共需时间 %d 分钟,费用 %d 元\n\n",system->routes[stack[i]][stack[b]].starttime.hour, system->routes[stack[i]][stack[b]].starttime.minute, system->routes[stack[i]][stack[b]].endtime.hour, system->routes[stack[i]][stack[b]].endtime.minute, system->routes[stack[i]][stack[b]].time, system->routes[stack[i]][stack[b]].cost);
		
		}
	
		printf("已经走完一个车次!\n");
		stack[top--];
		
		printf("\n");	
		return;
	}
	
	y[x]=1; 
	stack[top++]=x; //进栈 
	
	for(i=1;i<system->citycount;i++){
		if(!y[i]&&system->routes[x][i].time!=OVER) //如果i这个点没有被访问过,而且st与这个点相连,就继续搜索
			DFS1(system,i,z,p);
	}
	//当没有进行for循环中的DFS,代表着这次的DFS标记和队列无法到达终点。 
	y[x]=0;//删除标记 
	top--;//队列里删除x 
	
	
}

3. 通过城市名称,查询两城市间最省钱的搭乘方式

  为了找到两个城市间最省钱的搭乘方式,使用了迪杰斯特拉算法来寻找到了最短时间,之后遇到了如何输出中间所经过的城市的问题,最后在迪杰斯特拉算法中,加入了一个数组来记录每次的前驱,再通过一个函数来将两个城市间经过的城市保存在一个数组中,再通过数组的输出来实现。查询两城市间最省时间的搭乘方式仅仅换了对于钱和时间的寻找,跟最省钱没有什么区别。

void dijkstra(railysystem s, int startcity,int d[8],int f[8]) // 对于迪杰斯特拉的运用,来寻找最省钱的搭乘路线 
{
	int k=startcity;
	int final[MAX]; //标记是否经过 

int i;
	for (i = 0; i < s.citycount; i++) // 初始化 
	{
		d[i] = s.routes[startcity][i].cost;
		final[i] = 0;
		f[i] = -1;
	
	}

	d[startcity] = 0;
	final[startcity] = 1;
	int min;
int j;

	for ( i = 0; i < s.citycount; i++)
	{
		min = OVER;
		for (j = 0; j < s.citycount; j++)
		{
			if (!final[j] && d[j] < min) // 如果min大于当前d[j] 
			{
				k = j;
				min = d[j];
			
			}
		}
		
		final[k] = 1;
		for ( j = 0; j < s.citycount; j++)
		{
			if (!final[j] && (min + s.routes[k][j].cost) < d[j]) //找到更短的路径 
			{
				d[j] = min + s.routes[k][j].cost;
				f[j] = k;  // 标记j的前驱为k
		

			}
		}
	}



}

void xunzhao(int startcity,int endcity,int f[8],int a[8],int &m) // 对迪杰斯特拉用于标记前驱的f,来寻找两个城市中的转乘 
{

	if(f[endcity]!=-1)
	{
		a[m] = f[endcity];
		m++;
		xunzhao(startcity,f[endcity],f,a,m);
	}
}

void cheapquick(railysystem system, char startcity[MAX], char endcity[MAX]) { // 输出两城市间最省钱的搭乘方式 


	printf("查询两城市间最省钱的搭乘方式:\n");
	int z=-1,k=1,x=-1;
	while(k!=0)
	{
		x++;
     	k = strcmp(startcity,system.cities[x].name);
	}
	k = 1;
	while(k!=0)
	{
		z++;
     	k = strcmp(endcity,system.cities[z].name);
	}
	
	
	


	int min = OVER;
    int i;
	int d[8];
	int f[8];
	int a[8];
	int m=0;
	for(i=0;i<8;i++)
	{
		a[i] = -1;
	}
	dijkstra(system,x,d,f);
	xunzhao(x,z,f,a,m);
	bool r = false;
		for(i=7;i>=0;i--)
	{
		if(a[i]!=-1)
		{
			
			r = true;
			
			
		}
	}
	if (d[z]!=OVER&&r)
	{

		printf("最省钱的搭乘方式:%s 到 %s 最少花费:%d\n", system.cities[x].name, system.cities[z].name, d[z]);
		printf("途中经过站点:");
		for(i=7;i>=0;i--)
	{
		if(a[i]!=-1)
		{
			
			printf("%s ",system.cities[a[i]].name);
			
			
		}
	}
	printf("\n");
	int u;
		for(i=7;i>=0;i--)
	{
		if(a[i]!=-1)
		{
			
			u = a[i];
			break;
		}
		
	}
	
printf("车次号:%d 经过站点%s 转乘到 %s:出发时间:%d:%d 到站时间:%d:%d 共需时间 %d 分钟,费用 %d 元\n",system.routes[x][u].checi, system.cities[x].name, system.cities[u].name, system.routes[x][u].starttime.hour, system.routes[x][u].starttime.minute, system.routes[x][u].endtime.hour, system.routes[x][u].endtime.minute, system.routes[x][u].time, system.routes[x][u].cost);
			
		for(i=7;i>=0;i--)
	{
		if(a[i]!=-1)
		{
			int g = --i;
			i++;
			if(a[g]!=-1&&g!=-1)
			{
				printf("车次号:%d 经过站点%s 转乘到 %s:出发时间:%d:%d 到站时间:%d:%d 共需时间 %d 分钟,费用 %d 元\n",system.routes[a[i]][a[g]].checi, system.cities[a[i]].name, system.cities[a[g]].name, system.routes[a[i]][a[g]].starttime.hour, system.routes[a[i]][a[g]].starttime.minute, system.routes[a[i]][a[g]].endtime.hour, system.routes[a[i]][a[g]].endtime.minute, system.routes[a[i]][a[g]].time, system.routes[a[i]][a[g]].cost);
			}
			else
			{
			printf("车次号:%d 经过站点%s 转乘到 %s:出发时间:%d:%d 到站时间:%d:%d 共需时间 %d 分钟,费用 %d 元\n",system.routes[a[i]][z].checi,  system.cities[a[i]].name, system.cities[z].name, system.routes[a[i]][z].starttime.hour, system.routes[a[i]][z].starttime.minute, system.routes[a[i]][z].endtime.hour, system.routes[a[i]][z].endtime.minute, system.routes[a[i]][z].time, system.routes[a[i]][z].cost);
			}
			
			
			
		}
	}
	
	}
	else if (d[z]!=OVER&&!r)
	{
		printf("车次号:%d 最省钱的搭乘方式:%s 到 %s,出发时间:%d:%d,到站时间: %d:%d,花费时间:%d,最少花费:%d\n", system.routes[x][z].checi,system.cities[x].name, system.cities[z].name,system.routes[x][z].starttime.hour,system.routes[x][z].starttime.minute,system.routes[x][z].endtime.hour,system.routes[x][z].endtime.minute, system.routes[x][z].time,d[z]);
	}




	else {
		printf("无法找到两城市之间的搭乘方式\n");
	}

	printf("\n");
}

4.通过城市名称,寻找两个城市之间所有可以采用的搭乘方式

为了寻找两个城市间所有可以采用的搭乘方式,跟2一样同样使用了图的深度优先遍历,并使用了栈的性质,在输入两个城市的名字后,我遇到了如何找到城市对应的序号,我使用了一个函数来找到了城市对应的序号,再传入相应序号,来查询两个城市之间所有可以采用的搭乘方式。

int stack[MAX],y[MAX]={0},top=0; //为DFS作为标记和栈 
int q=0;


void xunzhao(int startcity,int endcity,int f[8],int a[8],int &m) // 对迪杰斯特拉用于标记前驱的f,来寻找两个城市中的转乘 
{

	if(f[endcity]!=-1)
	{
		a[m] = f[endcity];
		m++;
		xunzhao(startcity,f[endcity],f,a,m);
	}
}

void DFS(railysystem *system,int x,int z){ //通过DFS来寻找两个城市间的所有搭乘方式 
	int i;
	
	if(x==z){ //当st=et,代表已经找到了两个城市间的路径,可以打印 
	    stack[top++] = z;
	    q++;
	    printf("方式%d:\n",q);
		for(i=0;i<top-1;i++)
		{
	
			int b = ++i;
			i--;
			printf("车次号:%d %s->%s \n",system->routes[stack[i]][stack[b]].checi,system->cities[stack[i]],system->cities[stack[b]]);
            printf("出发时间:%d:%02d 到站时间:%d:%02d 共需时间 %d 分钟,费用 %d 元\n\n",system->routes[stack[i]][stack[b]].starttime.hour, system->routes[stack[i]][stack[b]].starttime.minute, system->routes[stack[i]][stack[b]].endtime.hour, system->routes[stack[i]][stack[b]].endtime.minute, system->routes[stack[i]][stack[b]].time, system->routes[stack[i]][stack[b]].cost);
            
		
		}
		stack[top--];
		
		printf("\n");	
		return;
	}
	y[x]=1;
	stack[top++]=x;
	for(i=1;i<system->citycount;i++){
		if(!y[i]&&system->routes[x][i].time!=OVER) //如果i这个点没有被访问过,而且st与这个点相连,就继续搜索
			DFS(system,i,z);
	}
	//当没有进行for循环中的DFS,代表着这次的DFS标记和队列无法到达终点。 
	y[x]=0;//删除标记 
	top--;//队列里删除x 
}

5.输入城市名称,并根据当前时间,查询出最快发出的列车及乘坐信息.

  我通过一个函数来寻找当前城市到另外城市的车次中,出发时间能否满足当前系统时间来乘坐,如果有就输出满足的车次信息,没有就打出无车次信息。后面发现如果出发时间一样,也应该一起打出来,多个选择,又加了个数组,先找出最近的,再通过对比加入数组,在通过数组,把全部最近的都输出来。对于系统时间的输入,也是学习了time.h的头文件的使用。

 

​
time_t t = time(NULL);
struct tm *tm = localtime(&t);

printf("%d:%d\n",tm->tm_hour,tm->tm_min);
imesystem(system,hcity,tm->tm_hour,tm->tm_min);



  void timesystem(railysystem system,char hcity[MAX],int localtime,int localminute) // 在某城市中,根据当前时间,查询出最快发出的列车及乘坐信息
{
	int k=1,x=-1;
	while(k!=0)
	{
		x++;
     	k = strcmp(hcity,system.cities[x].name);
	}

	int t=0;
	int u[MAX] = {0};
	
	int i,m,j=x;

	for(i=0;i<system.citycount;i++)
	{
		
		if(system.routes[x][i].time!=OVER)
		{  
			if(system.routes[x][i].starttime.hour>=localtime&&system.routes[x][j].starttime.hour>=system.routes[x][i].starttime.hour&&system.routes[x][j].starttime.minute>=system.routes[x][i].starttime.minute)
			{
				if(system.routes[x][i].starttime.hour==localtime&&system.routes[x][i].starttime.minute<localminute)
				{
					continue;
				}
				else
				{
					j = i;
				}
				
				
			}
			
		}
	}
	

	u[t] = j;
	
	for(i=0;i<system.citycount;i++)
	{
		
		if(system.routes[x][i].time!=OVER)
		{  
			if(system.routes[x][j].starttime.hour==system.routes[x][i].starttime.hour&&system.routes[x][j].starttime.minute==system.routes[x][i].starttime.minute&&j!=i)
			{
			t++;
			u[t] = i;
				
			}
		}
	}
	
		if(j==x)
	{
		printf("无列车车次");
		
	}
	else
	{
		for(i=0;i<=t;i++)
		{	
		printf("当前发出的最快列车车次:%d 城市:%s 到达城市:%s 出发时间:%d:%d 到站时间:%d:%d 共需时间:%d分钟 花费:%d元\n",system.routes[x][u[i]].checi,system.cities[x].name,system.cities[u[i]].name,system.routes[x][u[i]].starttime.hour,system.routes[x][u[i]].starttime.minute,system.routes[x][u[i]].endtime.hour,system.routes[x][u[i]].endtime.minute,system.routes[x][u[i]].time,system.routes[x][u[i]].cost);
		}
}
	}

​

总结

在整个铁路信息管理系统的实现过程中,学习了文件的使用和系统时间的使用,对于数据结构的运用也更加的熟练,其实代码并不是很完美,也比较繁杂,还是有非常大的改善空间的,还有很多数据结构并没有使用,主要用的也是邻接矩阵,也没用到邻接表,还有广度优先遍历以及FLORD也没用到,算是非常基础非常小的项目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值