簡易的C語言地鐵購票系統


大致思路:

將地鐵線路的抽象問題轉化為圖上最短路徑的具體問題,那么最大的難點如何抽象出來。

1.用結構體存儲每個站點的信息:包括編號、名稱、所經過的線路;

2.names數組存儲每個不通過站點的名字,其下表對應着站點的標號,這樣讀取數據時,可以利用它保證每個站點不被重復構建;

3.map二維數組存儲每個站點間的距離;

基本靠以上數據結構就可以將問題具體化了,然后就轉為圖上的路徑規划問題,利用dfs等算法即可解決。

 

效果展示(推薦dev進行代碼運行):

 

 

 

代碼:

純C版本:

#include <stdio.h>
#include <string.h>

// 站點信息 
typedef struct Station{
	char name[30]; // 站點名稱 
	int lines[20]; // 經過的線路 
	int cnt;       // 線路數量 
}Station; 
Station stations[100];
// 站點間收費
double map[100][100];
// 站點數量
int staNum; 
// 站點名稱
char names[100][30]; 
// 標記是否訪問過
int visit[100]; 
// 可選路線數量:
int ansNum; 
// 最優路線:
int minLu[100];
// 最優路線中站數量:
int minCnt;
// 最優價格:
double minPrict; 
// 當前線路:
int nowLu[100];

// 查找路線:
void dfs(int id1, int id2, int ct, double cost){
	int i, j;
	if(id1 == id2){
		printf("可選路線%d:\n", ++ansNum);
		for(i = 0; i < ct; i++){
			if(i == 0)
				printf("%s", names[nowLu[i]]);
			else
				printf(" -> %s", names[nowLu[i]]);
			printf("(");
			for(j = 0; j < stations[nowLu[i]].cnt; j++){
				printf("%d,", stations[nowLu[i]].lines[j]);
			}
			printf(")");
		}
		printf("   [費用:%lf]\n", cost);
		// 是否最優:
		if(cost < minPrict){
			minCnt = ct;
			minPrict = cost;
			for(i = 0; i < ct; i++){
				minLu[i] = nowLu[i];
			}
		} 
	} 
	for(i = 0; i < staNum; i++){
//		printf("%d %d %lf %d\n ", id1, id2, map[id1][i], 0x3f3f3f3f, visit[i]);
		if(i != id1 && map[id1][i] < 0x3f3f3f3f && visit[i] == 0){
			visit[i] = 1;
			nowLu[ct] = i;
//			printf("%d %d %d %d %d ",id1, id2, i, ct, nowLu[ct]);
			dfs(i, id2, ct + 1, cost + map[id1][i]);
			visit[i] = 0;
		}
	} 
	
} 

int main()
{
	// 讀入文件:包含線路信息 
    FILE *fp; 
	int i, j;  
	int id2;
    fp = fopen("data.txt","r"); //需要創建a.txt文件,然后寫入兩個數據,空格隔開
//    memset(map, 0x3f3f3f3f, sizeof(map)); 
	for (i = 0; i < 100; i++){
		for(j = 0; j < 100; j++){
			map[i][j] = 0x3f3f3f3f;
		}
	} 
    // 站點數量 
    staNum = 0;
	for(i = 1; i <= 5; i++){
		printf("[%d號線] ", i);
		while(1){
			double f=0;
		    char name1[30];
		    char name2[30];
		    fscanf( fp, "%s", &name1);
		    // 每條線路結束符規定為# 
		    if(name1[0] == '#'){
		    	printf("\n", i);
		    	break;
		    }
		    	
		    // 查找當前站點是否存在 
		    int id1 = -1;
			for(j = 0; j < staNum; j++){
				 if(strcmp(name1, names[j]) == 0){
				 	id1 = j;
				 	break;
				 }
			}
			// 如果當前站點不存在,則需要創建 
			if(id1 == -1){
				id1 = staNum; 
				strcpy(names[id1], name1);
//				stations[id1].name = name1; // 存入名字 
				strcpy(stations[id1].name, name1);
				stations[id1].lines[0] = i; // 存入線路 
				stations[id1].cnt = 1;      // 所經過的線路 
				staNum++;
			} 
			else{
				if (stations[id1].lines[stations[id1].cnt-1] != i){ //考慮是否需要把當前所在線路標號(即線路幾)存入該站點的lines
					stations[id1].lines[stations[id1].cnt] = i;
//					printf("||| i = %d, %s", i, name1);
					stations[id1].cnt++;	
				} 
			}
			// 讀入數據: 
		    fscanf( fp, "%s%lf", &name2, &f);
		    // 查找當前站點是否存在 
		    id2 = -1;
			for(j = 0; j < staNum; j++){
				 if(strcmp(name2, names[j]) == 0){
				 	id2 = j;
				 	break;
				 }
			}
			// 如果當前站點不存在,則需要創建 
			if(id2 == -1){
				id2 = staNum;
//				names[id2] = name2;
				strcpy(names[id2], name2);
//				stations[id2].name = name2; // 存入名字
				strcpy(stations[id2].name, name2);  
				stations[id2].lines[0] = i; // 存入線路 
				stations[id2].cnt = 1;      // 所經過的線路 
				staNum++;
			} 
			else{
				if(stations[id2].lines[stations[id2].cnt-1] != i){
					stations[id2].lines[stations[id2].cnt] = i;
//					printf("[ i = %d, %d %s] ", i, stations[id2].cnt, name2);
					stations[id2].cnt++;
				}
			}
			// 加入權重:
			map[id1][id2] = map[id2][id1] = f; 
		    printf("%s->%s %lf  ", name1, name2, f);
		}
		printf("\n");
	} 
//	for(int i = 0; i < staNum; i++){
//		printf("%s ", stations[i].name);
//		for(int j = 0; j < stations[i].cnt; j++){
//			printf("%d,", stations[i].lines[j]);
//		}
//		printf("\n");
//	}
//	printf("\n");
	// 打印矩陣:
//	for (int i = 0; i < staNum; i++){
//		for(int j = 0; j < staNum; j++){
//			printf("%lf ", map[i][j]);
//		}
//		printf("\n");
//	} 
	
	fclose(fp);
	
	// 功能啟動:
	while(1){
		// 輸入需要查找的線路:
		char n1[30];
		char n2[30];
		int i, j;

		// 查找當前站點是否存在 
	    int id1 = -1, id2 = -1;
	    printf("請輸入起始點和終點:\n");
		scanf("%s %s", n1, n2);
		for(j = 0; j < staNum; j++){
			 if(strcmp(n1, names[j]) == 0){
			 	id1 = j;
			 }
//			 else{
//			 	printf("%s %s\n", n1, names[j]);
//			 }
			 if(strcmp(n2, names[j]) == 0){
			 	id2 = j;
			 }
		}	 
//		printf("id1 %s id2 %s\n", n1, n2);
//		printf("您查找的起始點和終點分別是: %s -> %s\n", n1, n2);
    	if(id1 == -1 || id2 == -1){
    		printf("您輸入的名稱不存在!\n"); 
    		continue;
    	}
    	printf("您查找的起始點和終點分別是: %s -> %s\n", n1, n2);
    	// 清空數組 
    	memset(visit, 0, sizeof(visit)); 
    	// 可選路線數量 
		ansNum = 0; 
		nowLu[0] = id1;  // 放入起點 
		visit[id1] = 1;
		minPrict = 0x3f3f3f3f; // 初始化最優價格 
    	dfs(id1, id2, 1, 0);   // 起點, 終點, 路線中數據點個數, 價格 
		for(i = 0; i < minCnt; i++){
			if(i == 0)
				printf("最優路線:%s", names[minLu[i]]);
			else
				printf(" -> %s", names[minLu[i]]);
			printf("(");
			for(j = 0; j < stations[minLu[i]].cnt; j++){
				printf("%d,", stations[minLu[i]].lines[j]);
			}
			printf(")");
		}
		printf("   [費用:%lf]\n", minPrict);
    	printf("本次查找結束!!!\n\n");
	} 
    
    return 0;
}

  

 

 

 

 C++版:

#include <stdio.h>
#include <string.h>

// 站點信息 
typedef struct Station{
	char name[30]; // 站點名稱 
	int lines[20]; // 經過的線路 
	int cnt;       // 線路數量 
}Station; 
Station stations[100];
// 站點間收費
double map[100][100];
// 站點數量
int staNum; 
// 站點名稱
char names[100][30]; 
// 標記是否訪問過
int visit[100]; 
// 可選路線數量:
int ansNum; 
// 最優路線:
int minLu[100];
// 最優路線中站數量:
int minCnt;
// 最優價格:
double minPrict; 
// 當前線路:
int nowLu[100];

// 查找路線:
void dfs(int id1, int id2, int ct, double cost){
	if(id1 == id2){
		printf("可選路線%d:\n", ++ansNum);
		for(int i = 0; i < ct; i++){
			if(i == 0)
				printf("%s", names[nowLu[i]]);
			else
				printf(" -> %s", names[nowLu[i]]);
			printf("(");
			for(int j = 0; j < stations[nowLu[i]].cnt; j++){
				printf("%d,", stations[nowLu[i]].lines[j]);
			}
			printf(")");
		}
		printf("   [費用:%lf]\n", cost);
		// 是否最優:
		if(cost < minPrict){
			minCnt = ct;
			minPrict = cost;
			for(int i = 0; i < ct; i++){
				minLu[i] = nowLu[i];
			}
		} 
	} 
	for(int i = 0; i < staNum; i++){
//		printf("%d %d %lf %d\n ", id1, id2, map[id1][i], 0x3f3f3f3f, visit[i]);
		if(i != id1 && map[id1][i] < 0x3f3f3f3f && visit[i] == 0){
			visit[i] = 1;
			nowLu[ct] = i;
//			printf("%d %d %d %d %d ",id1, id2, i, ct, nowLu[ct]);
			dfs(i, id2, ct + 1, cost + map[id1][i]);
			visit[i] = 0;
		}
	} 
	
} 

int main()
{
	// 讀入文件:包含線路信息 
    FILE *fp;   
    fp = fopen("data.txt","r"); //需要創建a.txt文件,然后寫入兩個數據,空格隔開
//    memset(map, 0x3f3f3f3f, sizeof(map)); 
	for (int i = 0; i < 100; i++){
		for(int j = 0; j < 100; j++){
			map[i][j] = 0x3f3f3f3f;
		}
	} 
    // 站點數量 
    staNum = 0;
	for(int i = 1; i <= 5; i++){
		printf("[%d號線] ", i);
		while(1){
			double f=0;
		    char name1[30];
		    char name2[30];
		    fscanf( fp, "%s", &name1);
		    // 每條線路結束符規定為# 
		    if(name1[0] == '#'){
		    	printf("\n", i);
		    	break;
		    }
		    	
		    // 查找當前站點是否存在 
		    int id1 = -1;
			for(int j = 0; j < staNum; j++){
				 if(strcmp(name1, names[j]) == 0){
				 	id1 = j;
				 	break;
				 }
			}
			// 如果當前站點不存在,則需要創建 
			if(id1 == -1){
				id1 = staNum; 
				strcpy(names[id1], name1);
//				stations[id1].name = name1; // 存入名字 
				strcpy(stations[id1].name, name1);
				stations[id1].lines[0] = i; // 存入線路 
				stations[id1].cnt = 1;      // 所經過的線路 
				staNum++;
			} 
			else{
				if (stations[id1].lines[stations[id1].cnt-1] != i){
					stations[id1].lines[stations[id1].cnt] = i;
//					printf("||| i = %d, %s", i, name1);
					stations[id1].cnt++;	
				} 
			}
			// 讀入數據: 
		    fscanf( fp, "%s%lf", &name2, &f);
		    // 查找當前站點是否存在 
		    int id2 = -1;
			for(int j = 0; j < staNum; j++){
				 if(strcmp(name2, names[j]) == 0){
				 	id2 = j;
				 	break;
				 }
			}
			// 如果當前站點不存在,則需要創建 
			if(id2 == -1){
				id2 = staNum;
//				names[id2] = name2;
				strcpy(names[id2], name2);
//				stations[id2].name = name2; // 存入名字
				strcpy(stations[id2].name, name2);  
				stations[id2].lines[0] = i; // 存入線路 
				stations[id2].cnt = 1;      // 所經過的線路 
				staNum++;
			} 
			else{
				if(stations[id2].lines[stations[id2].cnt-1] != i){
					stations[id2].lines[stations[id2].cnt] = i;
//					printf("[ i = %d, %d %s] ", i, stations[id2].cnt, name2);
					stations[id2].cnt++;
				}
			}
			// 加入權重:
			map[id1][id2] = map[id2][id1] = f; 
		    printf("%s->%s %lf  ", name1, name2, f);
		}
		printf("\n");
	} 
//	for(int i = 0; i < staNum; i++){
//		printf("%s ", stations[i].name);
//		for(int j = 0; j < stations[i].cnt; j++){
//			printf("%d,", stations[i].lines[j]);
//		}
//		printf("\n");
//	}
//	printf("\n");
	// 打印矩陣:
//	for (int i = 0; i < staNum; i++){
//		for(int j = 0; j < staNum; j++){
//			printf("%lf ", map[i][j]);
//		}
//		printf("\n");
//	} 
	
	fclose(fp);
	
	// 功能啟動:
	while(1){
		// 輸入需要查找的線路:
		char n1[30];
		char n2[30];
		printf("請輸入起始點和終點:\n");
		scanf("%s %s", n1, n2);
		// 查找當前站點是否存在 
	    int id1 = -1, id2 = -1;
		for(int j = 0; j < staNum; j++){
			 if(strcmp(n1, names[j]) == 0){
			 	id1 = j;
			 }
//			 else{
//			 	printf("%s %s\n", n1, names[j]);
//			 }
			 if(strcmp(n2, names[j]) == 0){
			 	id2 = j;
			 }
		}	 
//		printf("id1 %s id2 %s\n", n1, n2);
//		printf("您查找的起始點和終點分別是: %s -> %s\n", n1, n2);
    	if(id1 == -1 or id2 == -1){
    		printf("您輸入的名稱不存在!\n"); 
    		continue;
    	}
    	printf("您查找的起始點和終點分別是: %s -> %s\n", n1, n2);
    	// 清空數組 
    	memset(visit, 0, sizeof(visit)); 
    	// 可選路線數量 
		ansNum = 0; 
		nowLu[0] = id1;  // 放入起點 
		visit[id1] = 1;
		minPrict = 0x3f3f3f3f; // 初始化最優價格 
    	dfs(id1, id2, 1, 0);   // 起點, 終點, 路線中數據點個數, 價格 
		for(int i = 0; i < minCnt; i++){
			if(i == 0)
				printf("最優路線:%s", names[minLu[i]]);
			else
				printf(" -> %s", names[minLu[i]]);
			printf("(");
			for(int j = 0; j < stations[minLu[i]].cnt; j++){
				printf("%d,", stations[minLu[i]].lines[j]);
			}
			printf(")");
		}
		printf("   [費用:%lf]\n", minPrict);
    	printf("本次查找結束!!!\n\n");
	} 
    
    return 0;
}

  

數據:

a b 4 b c 10 c d 7 d e 4 #
f g 3 g c 8 c h 4 h i 1 i j 7 #
k l 4 l m 7 m d 3 d n 2 n o 1 #
p l 2 l q 1 q r 3 r s 5 s t 9 #
u t 1 t v 9 v d 3 d w 7 w x 3 x y 2 #

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM