基于C++的数据结构课程设计-交通咨询系统

目录

​编辑

一、题目与设计内容

二、需求分析

1.设计要求:

2.规定:

三、概要设计

1.抽象数据类型的定义:

2.数据的逻辑结构:

3.主程序流程:

四、调用关系图

五、程序代码

六、测试结果

七、尾言


一、题目与设计内容

 交通咨询系统设计

设计内容:

  设计一个交通咨询系统,能让旅客咨询从任一个城市定点到另一个城市定点之间的最短路径或最低花费或最少时间等问题。对于不同的咨询要求、可输入城市间的路程或所需时间或所需花费。

二、需求分析

1.设计要求:

        1.     建立交通网络网的存储结构。

        2.     总体设计要画流程图。

        3.     提供程序测试方案。

        4.     界面友好。

2.规定:

        1.输入的形式和输入值的范围: 在程序中输入城市名称时,需输入20个字符以内的字符串;

        2.输出的形式:最短路径;

        3.程序所能达到的功能:熟练掌握迪杰斯特拉算法和费洛伊德算法,能够利用它们解决最短路径问题;能够解决工程项目实施过程中的关键路径问题;

        4.测试数据:通过输入不同的省会,得到最短的距离。

三、概要设计

1.抽象数据类型的定义:

class Gragh

{

private:

    const char* a[34];

    int edge[34][34];

    int n, e, path_num;

    bool Mark[34];

    int Path[50][11];

    int Path_date[50];

    int result[34];

public:

    Gragh();                                                 

    void creat_Gragh();                                          

    int find(string str);                                    

    void BFT(Gragh g);                                           

    void Dijkstra(string str1, string str2, string str3 = "无");     

    void Floyd(string str1, string str2, string str3 = "无");         

    void All_Load(string str1, string str2);                          

    void Find_All_Load(int pos1, int pos2);                      

    void A_star(string str1, string str2, int k);            

};

struct edge1                                             

    int num;

    int cost, last_cost;                            

    string str;

    bool operator <(const edge1& s)const       

    {

         return cost > s.cost;

    };

2.数据的逻辑结构:

       根据设计任务的描述,其城市之间的交通问题是典型的图结构,可看作为有向图,图的顶点是城市,边是城市之间所耗费的里程。

3.主程序流程:

     主程序可以有系统界面、菜单;也可用命令提示方式;选择功能模块执行,要求在程序运行过程中可以反复操作。说明本程序中用到的所有抽象数据类型的定义、数据的逻辑结构、主程序的流程以及各程序模块之间的层次(调用)关系。

四、调用关系图

五、程序代码

graph.h:
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<queue>
#include<stack>
using namespace std;
const int MAX = 10000;
void quickSort(int left, int right, int a[], string s[], int size);


class Gragh
{
private:
	const char* a[34];
	int edge[34][34];
	int n, e, path_num;
	bool Mark[34];
	int Path[50][11];
	int Path_date[50];
	int result[34];
public:
	Gragh();												
	void creat_Gragh();										
	int find(string str);									
	void BFT(Gragh g);										
	void Dijkstra(string str1, string str2, string str3 = "无");		
	void Floyd(string str1, string str2, string str3 = "无");			
	void All_Load(string str1, string str2);						
	void Find_All_Load(int pos1, int pos2);						
	void A_star(string str1, string str2, int k);			
};

struct edge1											
	int num;
	int cost, last_cost;							
	string str;
	bool operator <(const edge1& s)const		
	{
		return cost > s.cost;
	}
};



Gragh::Gragh()						
{
	for (int i = 0; i < 50; i++)
	{
		Path_date[i] = 0;
		for (int j = 0; j < 11; j++)
			Path[i][j] = -1;
	}

	for (int i = 0; i < 34; i++)
	{
		Mark[i] = false;
		result[i] = 0;
		for (int j = 0; j < 34; j++)
		{
			if (i == j) edge[i][j] = 0;
			else edge[i][j] = MAX;
		}
	}
	n = 0;
	path_num = 0;
}


void Gragh::creat_Gragh()				
{
	int temp[600] = { 0 };
	string str;
	{
		ifstream fin_2("2.csv");
		for (int tem = 0; fin_2.eof() == false; tem++)
		{
			getline(fin_2, str, ',');
			if (str == "0")
			{
				getline(fin_2, str, '\n');
				getline(fin_2, str, ',');
				cin.sync();
			}
			istringstream is(str);
			is >> temp[tem];
		}
	}
	ifstream fin_3("3.csv");
	for (int i = 0; i < 34; i++)
	{

		getline(fin_3, str, ',');
		string* str_1 = new string(str);
		a[i] = str_1->c_str();
	}
	ifstream fin_1("1.csv");
	for (int i = 0; i < 34; i++)
	{
		for (int j = 0; j < 34; j++)
		{
			if (j == 33)
			{
				getline(fin_1, str, '\n');
				if (str != "1" || j < i) continue;
				edge[j][i] = edge[i][j] = temp[(j * j - j) / 2 + i];
			}
			getline(fin_1, str, ',');
			if (str != "1" || j < i) continue;
			edge[j][i] = edge[i][j] = temp[(j * j - j) / 2 + i];
		}
	}
}

int Gragh::find(string str)				
{
	if (str == "无")  return 0;			
	for (int i = 0; i < 34; i++)
	{
		if (a[i] == str) return i;
	}
	return -1;
}

void Gragh::BFT(Gragh g)			
{
	int have[34] = { 0 };
	have[22] = 1;					
	int num = 0;						
	queue<int> q1;					
	for (int i = 0; i < 34; i++)
	{
		if (g.edge[22][i] < MAX && g.edge[22][i]>0)
		{
			q1.push(i);
			have[i] = 1;
		}
	}
	q1.push(-1);					
	while (!q1.empty())
	{
		int i = q1.front();
		q1.pop();
		if (i == -1)				
		{
			cout << endl;
			cout << "上面城市需要" << num << "次中转即可到达" << endl;
			cout << endl;
			if (q1.empty()) return;		
			q1.push(-1);
			num++;
			continue;
		}
		cout << a[i] << " ";
		for (int j = 0; j < 34; j++)	
		{
			if (g.edge[i][j] < MAX && g.edge[i][j]>0 && have[j] == 0)
			{
				have[j] = 1;			
				q1.push(j);
			}
		}
	}
}

void Gragh::Dijkstra(string str1, string str2, string str3)		
{
	int i, j, k, w, min, pos1 = find(str1), pos2 = find(str2), pos3 = find(str3), temp = pos1;
	if (pos1 == -1 || pos2 == -1 || pos3 == -1)
	{
		cout << "本路线图不存在您所给出的城市,请重试" << '\n';
		return;
	}
	int dist[34], path[34];		
	bool s[34];
	for (i = 0; i < 34; i++)			
	{
		dist[i] = edge[pos1][i];
		s[i] = false;
		if (i != pos1 && dist[i] < MAX && dist[i]>0) path[i] = pos1;
		else path[i] = -1;
	}
	s[pos1] = true;
	dist[pos1] = 0;
	for (i = 0; i < 33; i++)
	{
		if (i == pos3) continue;			
		min = MAX;
		int u = pos1;
		for (j = 0; j < 34; j++)
		{
			if (j == pos3) continue;		
			if (!s[j] && dist[j] < min)
			{
				u = j;
				min = dist[j];
			}
		}
		s[u] = true;
		for (k = 0; k < 34; k++)
		{
			if (k == pos3) continue;		
			w = edge[u][k];
			if (!s[k] && w < MAX && dist[u] + w < dist[k])
			{
				dist[k] = dist[u] + w;
				path[k] = u;
			}
		}
	}
	k = path[pos2];
	if (k == -1)
	{
		cout << "此路径不存在" << '\n';
		return;
	}
	stack<int> sta;						
	cout << str1;
	while (k != pos1)
	{
		sta.push(k);					
		k = path[k];
	}
	while (!sta.empty())
	{
		cout << "->" << a[sta.top()];
		sta.pop();
	}
	cout << "->" << str2 << "  " << "距离为" << dist[pos2] << endl;
}

void Gragh::Floyd(string str1, string str2, string str3)
{				
	int i, j, k, pos1 = find(str1), pos2 = find(str2), pos3 = find(str3), temp = pos1;
	if (pos1 == -1 || pos2 == -1 || pos3 == -1)
	{
		cout << "本路线图不存在您所给出的城市,请重试" << '\n';
		return;
	}
	int min[34][34], path[34][34];			
	for (i = 0; i < 34; i++)
		for (j = 0; j < 34; j++)
		{
			min[i][j] = edge[i][j];
			path[i][j] = j;
		}
	pos1 = temp;
	for (k = 0; k < 34; k++)
	{
		if (k == pos3) continue;
		for (i = 0; i < 34; i++)
		{
			if (i == pos3) continue;
			for (j = 0; j < 34; j++)
			{
				if (j == pos3) continue;
				if (min[i][j] > min[i][k] + min[k][j])
				{
					min[i][j] = min[i][k] + min[k][j];
					path[i][j] = path[i][k];
				}
			}
		}
	}
	k = path[pos1][pos2];
	if (k == pos2)
	{
		cout << "此路径不存在" << '\n';
		return;
	}
	cout << str1;
	while (k != pos2)
	{
		cout << "->" << a[k];
		k = path[k][pos2];
	}
	cout << "->" << str2 << "  " << "距离为" << min[pos1][pos2] << endl;
}

void Gragh::All_Load(string str1, string str2)
{
	string s[100];
	int date[100];
	int pos1 = find(str1);
	int pos2 = find(str2);
	if (pos1 == -1 || pos2 == -1)
	{
		cout << "未查询到城市名字,请重新再试" << endl;
		return;
	}
	Find_All_Load(pos1, pos2);
	for (int i = 0; i < path_num; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			s[i] += a[Path[i][j]];				
			if (Path[i][j + 1] == -1) break;
			s[i] += "->";
		}
	}
	quickSort(0, path_num, Path_date, s, path_num + 1);		
	ofstream out("path_date.txt");					
	if (!out) { cout << "不能打开文件!" << endl; return; }
	for (int i = 0; i < path_num; i++)
	{
		out << s[i] << "  路径长度为" << Path_date[i] << endl;
	}
	cout << "已保存在文件中" << endl;
}

void Gragh::Find_All_Load(int pos1, int pos2)
{
	if (n > 5) return;			
	result[n] = pos1;			
	Mark[pos1] = true;			
	n++;
	while (n != 0)
	{
		int temp = result[n - 1];
		if (temp == pos2)		
		{
			for (int i = 0; i < n; i++)
			{
				Path[path_num][i] = result[i];
				if (i != 0) Path_date[path_num] += edge[result[i - 1]][result[i]];
			}
			n--;				
			path_num++;			
			result[n] = 0;
			Mark[pos2] = false;
			break;
		}
		for (int j = 0; j < 34; j++)		
		{
			if (edge[temp][j] > 0 && edge[temp][j] < MAX)
			{
				if (Mark[j] == false)		
				{
					Find_All_Load(j, pos2);
				}
			}
		}
		n--;			
		result[n] = 0;
		Mark[pos1] = false;
		break;
	}
}


void quickSort(int left, int right, int a[], string s[], int size)		
{
	if (left >= right) 
		return;
	if (left < 0 || right >= size)
	{
		cout << "error args! aay bound." << endl;
		return;
	}
	int i, j, base, temp;
	i = left, j = right;
	base = a[left];  
	while (i < j)
	{
		while (a[j] <= base && i < j)
			j--;
		while (a[i] >= base && i < j)
			i++;
		if (i < j)
		{
			swap(s[i], s[j]);			
			temp = a[i];
			a[i] = a[j];
			a[j] = temp;
		}
	}
	//基准数归位
	a[left] = a[i];
	a[i] = base;
	swap(s[i], s[left]);
	quickSort(left, i - 1, a, s, size);
	quickSort(i + 1, right, a, s, size);
}

void Gragh::A_star(string str1, string str2, int k_num)
{			
	int i, j, k, w, min, pos1 = find(str2), pos2 = find(str1), temp = pos1;
	if (pos1 == -1 || pos2 == -1)
	{
		cout << "本路线图不存在您所给出的城市,请重试" << '\n';
		return;
	}
	int dist[34], path[34];
	bool s[34];
	for (i = 0; i < 34; i++)
	{
		dist[i] = edge[pos1][i];
		s[i] = false;
		if (i != pos1 && dist[i] < MAX && dist[i]>0) path[i] = pos1;
		else path[i] = -1;
	}
	s[pos1] = true;
	dist[pos1] = 0;
	for (i = 0; i < 33; i++)
	{
		min = MAX;
		int u = pos1;
		for (j = 0; j < 34; j++)
		{
			if (!s[j] && dist[j] < min)
			{
				u = j;
				min = dist[j];
			}
		}
		s[u] = true;
		for (k = 0; k < 34; k++)
		{
			w = edge[u][k];
			if (!s[k] && w < MAX && dist[u] + w < dist[k])
			{
				dist[k] = dist[u] + w;
				path[k] = u;
			}
		}

	}

	priority_queue <edge1> Q;			
	edge1 tem;							
	tem.cost = dist[pos2];
	tem.num = pos2;
	tem.last_cost = 0;
	tem.str = str1;
	Q.push(tem);
	while (!Q.empty())
	{
		tem = Q.top();
		Q.pop();
		if (tem.num == pos1)	
			if (--k_num == 0)	
			{
				cout << tem.str << " 路径长度为" << tem.cost << endl;
				return;
			}
		for (int i = 0; i < 34; i++)
		{
			if (edge[tem.num][i] <= 0 || edge[tem.num][i] >= MAX) continue;

			edge1 tp;
			tp.str = tem.str + "->" + a[i];
			tp.num = i;
			tp.cost = tem.last_cost + edge[tem.num][tp.num] + dist[tp.num];
			tp.last_cost = tem.last_cost + edge[tem.num][i];
			Q.push(tp);
		}
		
	}
	return;
}

void menu()
{
	cout << "       ------------------------------------------------------------------" << endl;
	cout << "       |                                                                 | " << endl;
	cout << "       |     如需验证武汉中心地位请按                         1          | " << endl;
	cout << "       |     如需使用Dijkstra查询两城市之间的最短距离请按     2          | " << endl;
	cout << "       |     如需使用Floyd查询两城市之间的最短距离请按        3          | " << endl;
	cout << "       |     如需输出所有路径请按                             4          | " << endl;
	cout << "       |     如需求出两城市间第k短距离请按                    5          | " << endl;
	cout << "       |     如需退出系统请按                                 0          |" << endl;
	cout << "       |                                                                 | " << endl;
	cout << "        -----------------------------------------------------------------" << endl;
}
graph.cpp:
#include <iostream>
#include <string>
#include "graph.h"
using namespace std;


int main()
{
	int k;
	int k_num;
	Gragh g;
	g.creat_Gragh();
	string str1, str2, str3;
	while (1)
	{
		menu();
		cout << "请问您要执行哪一个功能呢,请输入相应数字" << endl;
		cin >> k;
		switch (k)
		{
		case 1:
			g.BFT(g);
			break;
		case 2:
			cout << "请输入您想要查询的两城市名字" << endl;
			cin >> str1 >> str2;
			cout << "您是否有想过要绕过的城市(如有则输入城市名称,如无则输入“0”)" << endl;
			cin >> str3;
			if (str3 == "0") g.Dijkstra(str1, str2);
			else g.Dijkstra(str1, str2, str3);
			break;
		case 3:
			cout << "请输入您想要查询的两城市名字" << endl;
			cin >> str1 >> str2;
			cout << "您是否有想过要绕过的城市(如有则输入城市名称,如无则输入“0”)" << endl;
			cin >> str3;
			if (str3 == "0") g.Floyd(str1, str2);
			else g.Floyd(str1, str2, str3);
			break;
		case 4:
			cout << "请输入您想要查询的两城市名字" << endl;
			cin >> str1 >> str2;
			g.All_Load(str1, str2);
			break;
		case 5:
			cout << "请输入您想要查询的两城市名字" << endl;
			cin >> str1 >> str2;
			cout << "请输入k的值" << endl;
			cin >> k_num;
			g.A_star(str1, str2, k_num);
			break;
		case 0:
			exit(0);
		default:
			break;
		}
	}
}

六、测试结果

七、尾言

        在本文中,我们探讨了设计一个交通咨询系统的全过程,该系统允许旅客查询从一个城市到另一个城市的最短路径、最低花费或最少时间等关键信息。我们首先进行了需求分析,明确了系统的设计要求和规定。接下来,我们进行了概要设计,包括抽象数据类型的定义、数据的逻辑结构以及主程序流程的设计。这些步骤为编写具体的程序代码打下了坚实的基础。

        在实现阶段,我们采用了C++语言和合适的数据结构来编码交通咨询系统,确保它能够高效地处理城市间路径、时间及费用信息的查询。我们通过调用关系图来展示系统中各个组件如何相互作用。完成编写后,我们进行了程序的测试,验证系统能否正常运行并生成正确的咨询结果。

        测试结果表明,该系统能够准确地回答用户关于城市间最短路径、最低花费和最少时间等的查询。它在功能上表现稳定,用户界面友好,易于旅客使用,能够快速得到他们所需的重要旅行信息。

        综上所述,我们的交通咨询系统设计是成功的。它不仅满足了旅客查询交通信息的需求,还展示了如何将理论知识应用于解决实际问题的过程。随着交通数据的不断更新和变化,系统应能容易地进行维护和升级,以适应未来的发展和扩大服务范围。我们希望这个系统能够为旅客提供便利,并提高他们的旅行体验。

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
设计、实现一个全国大城市间的交通咨询程序,为旅客提供三种最优决策方案:一是建立交通网络图的存储结构,二实现两个城市间的最短路经问题。程序所具有的功能特色本程序主要目的是为了给用户提供路径咨询。实现了帮助用户了解全国各大城市间往来的最短路径问题,第二,可以提供用户查询各大城市的相关信息。本程序最大的特点是支持用户自己添加城市信息及城市,或添加城市的路径,既就有可扩展性 该程序所做的工作的是模拟全国交通咨询,为旅客提供三种最优决策的交通咨询。此程序规定: (1) 在程序中输入城市名称时,需输入10个字母以内的字母串;输入列车或飞机编号时需输入一个整型数据;输入列车或飞机的费用时需输入一个实型数据;输入列车或飞机开始时间和到达时间时均需输入两个整型数据(以hh:mm的形式);在选择功能时,应输入与所选功能对应的一个整型数据。 (2) 程序的输出信息主要是:最快需要多少时间才能到达,或最少需要多少旅费才能到达,或最少需要多少次中转到达,并详细说明依次于何时乘坐哪一趟列车或哪一次班机到何地。 (3) 程序的功能包括:提供对城市信息的编辑,提供列车时刻表和飞机航班表的编辑,提供三种最优决策:最快到达、最省钱到达、最少中转次数到达。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

4.0啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值