⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 roaddlg.cpp

📁 公交查询系统 实现了站点查询
💻 CPP
字号:
// RoadDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Road.h"
#include "RoadDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

struct all
{
public:
	char TruckName[8];//车名
	int Num;//地址数
	char name[40][16];//地址名
}AllRoad[NUM];//定义车名与地址的对象,用于存放数据文件

struct Belong
{
public:
		char m_Name[20];//地址名
	    char m_TruckName[EveryTruckRoadNum][10];
		int m_IndexRoad[EveryTruckRoadNum];//车名在AllRoad[]中的位置
		int m_IndexName[EveryTruckRoadNum];//地址名在AllRoad.name[]中的位置
		int m_Result;//地址所在车名个数
}BeginName,EndName;//起点所在站点,终点所在站点

CString m_csChoose;
CString Way[WayNum];//为选择最短路径用500个数组
int WayLong[WayNum];//为选择最短路径用500个数组,路线长度
int CheckWay;//为选择最短路径用
int m_ClearIndex;
bool check;//这是标志着是否找到了路线,TRUE为找到了

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRoadDlg dialog

CRoadDlg::CRoadDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CRoadDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CRoadDlg)
	m_result_last = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CRoadDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRoadDlg)
	DDX_Control(pDX, IDC_ENDNAME, m_EndName);
	DDX_Control(pDX, IDC_BEGINNAME, m_BeginName);
	DDX_Text(pDX, IDC_RESULT, m_result_last);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CRoadDlg, CDialog)
	//{{AFX_MSG_MAP(CRoadDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRoadDlg message handlers

BOOL CRoadDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	
	/////////////////////////////////////////
	FILE *fp;
	fp = fopen("souce.txt","r");
	if(fp == NULL)AfxMessageBox("请将souce.txt拷贝到Road工程目录中");
	for(int j = 0;j < NUM;j ++)
	{
		fscanf(fp,"%5s%d",& AllRoad[j].TruckName,& AllRoad[j].Num);
		for(int i = 0;i < AllRoad[j].Num;i ++)
		{
			fscanf(fp,"%s",AllRoad[j].name[i]);
		}
	}
	fclose(fp);
	//上述模块把文件读入到内存
	////////////////////////////////////////
	struct Name
	{
		char name[16];
		struct Name * next;
	};
	struct Name * head,* p1,* p2;
	p2 = p1 = head = (struct Name *)malloc(sizeof(struct Name));
	strcpy (p1 -> name,AllRoad[0].name[0]);
	p1 -> next = NULL;
	m_EndName.AddString(p1 -> name);
	m_BeginName.AddString(p1 -> name);
	for(int i = 0; i < NUM; i ++)
	{
		for(int j = 0; j < AllRoad[i].Num; j ++)
		{
			p1 = head;
			while(p1 != NULL)
			{
				if(strcmp(p1 -> name,AllRoad[i].name[j]) != 0)
					p1 = p1 -> next;
				else break;
			}
			if(p1 == NULL)
			{
				p1 = (struct Name *)malloc(sizeof(struct Name));
				strcpy(p1 -> name,AllRoad[i].name[j]);
				p2 -> next = p1;
				p2 = p2 -> next;
				m_EndName.AddString(p1 -> name);
				m_BeginName.AddString(p1 -> name);
				p1 -> next = NULL;
			}
		}
	}
	//上述模块把两个CombBox的内容进行初始化,使得相同的车站名只出现一次  
	return true; //unless you set the focus to a control
}

void CRoadDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CRoadDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CRoadDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CRoadDlg::OnOK() 
{
	strcpy(BeginName.m_Name," ");
	strcpy(EndName.m_Name," ");
	for(int i = 0;i < EveryTruckRoadNum;i ++)
	{
		strcpy(BeginName.m_TruckName[i]," ");
		strcpy(EndName.m_TruckName[i]," ");
		BeginName.m_IndexRoad[i] = 0;
		EndName.m_IndexName[i] = 0;
		BeginName.m_IndexRoad[i] = 0;
		EndName.m_IndexName[i] = 0;
	}
	BeginName.m_Result = 0;
	EndName.m_Result = 0;
	for(i = 0;i < WayNum;i ++)
	{
		Way[i] = " ";
		WayLong[i] = 0;
	}
	CheckWay = 0;
	//上述代码是对所定义的结构进行初始化,全部清除内容
	UpdateData();
	m_BeginName.GetLBText(m_BeginName.GetCurSel(),BeginName.m_Name);
	m_EndName.GetLBText(m_EndName.GetCurSel(),EndName.m_Name);
	for(int j = 0;j < NUM; j ++)//此循环是查找路段所在的站名
	{
		for(int i = 0;i < AllRoad[j].Num;i ++)
		{
			if(strcmp(BeginName.m_Name,AllRoad[j].name[i]) == 0)
			{
				//把起始站名存在BeginBlong[]中
				strcpy(BeginName.m_TruckName[BeginName.m_Result],AllRoad[j].TruckName);
				//记录该站点在AllRoad[]中的索引号
				BeginName.m_IndexRoad[BeginName.m_Result] = j;
				//记录该站点在AllRoad[].name[]中的索引号
				BeginName.m_IndexName[BeginName.m_Result] = i;
				BeginName.m_Result ++;
			}
			if(strcmp(EndName.m_Name,AllRoad[j].name[i]) == 0)
			{
				//把终止站名存在EndBlong[]中
				strcpy(EndName.m_TruckName[EndName.m_Result],AllRoad[j].TruckName);
				//记录该站点在AllRoad[]中的索引号
				EndName.m_IndexRoad[EndName.m_Result] = j;
				//记录该站点在AllRoad[].name[]中的索引号
				EndName.m_IndexName[EndName.m_Result] = i;
				EndName.m_Result ++;
			}
		}
	}
	//上述代码是对数据进行处理,并建立索引
	CheckWhetherInTheSameTruck();//检查两个地址是否在同一车名上

}
//检查起点和终点是否在同一车名上的函数
void CRoadDlg::CheckWhetherInTheSameTruck()
{
	int i,j;
	CString temp(" ");
	m_result_last = " ";
	int num = 0;
	check = false;//如果直达,则值为true,否则为false
	for(i = 0;i < BeginName.m_Result;i ++)
		for(j = 0;j < EndName.m_Result;j ++)
		{
			if(strcmp(BeginName.m_TruckName[i],EndName.m_TruckName[j]) == 0)
			{
				WayLong[num] = abs(BeginName.m_IndexName[i] - EndName.m_IndexName[j]);
			    Way[num].Format("所乘的车是:%s,共%d站到\r\n",BeginName.m_TruckName[i],abs(BeginName.m_IndexName[i] - EndName.m_IndexName[j]));
				if(BeginName.m_IndexName[i] > EndName.m_IndexName[j])
					for(int k = BeginName.m_IndexName[i];k >= EndName.m_IndexName[j];k --)
					{
						if(k == EndName.m_IndexName[j])
							temp.Format("%s",AllRoad[BeginName.m_IndexRoad[i]].name[k]);							
						else 
							temp.Format("%s-",AllRoad[BeginName.m_IndexRoad[i]].name[k]);							
						Way[num] += temp;
					}
					else 
						for(int l = BeginName.m_IndexName[i];l <= EndName.m_IndexName[j];l ++)
						{
							if(l == EndName.m_IndexName[j])
								temp.Format("%s",AllRoad[BeginName.m_IndexRoad[i]].name[l]);
							else 
								temp.Format("%s-",AllRoad[BeginName.m_IndexRoad[i]].name[l]);
						    Way[num] += temp;
						}
						check = true;
						num ++;
						CheckWay ++;
			}
		}
		if(check) 
			ChoseShortestWay();
		else 
			SecondCheck();		
}
//选择最短路径函数
void CRoadDlg::ChoseShortestWay()
{
	int WayIndex = WayLong[0];
	int num = 1;
	CString temp(" ");
	for(int s = 0;s < CheckWay - 1;s ++)
	{
		if(WayIndex > WayLong[s + 1])
		    WayIndex = WayLong[s + 1];
	}//遍历所有的路线长度,找出最短的长度
	temp.Format("共经过%d站\r\n",WayIndex);
	for(s = 0;s < CheckWay;s ++)
	{
		if(WayIndex == WayLong[s] )
		{
			temp.Format("方法%d:%s\r\n\r\n",num ++,Way[s]);
		    m_result_last += temp;
		}//如果是最短的则输出
	}
	UpdateData(false);
}
//二次查询函数
void CRoadDlg::SecondCheck()
{
	check = false;
	int PathLength = 0;
	CString StationName = " ";
	CString temp = " ";
	int result = 0;//如果结果很多,进行调试
	for(int a = 0;a < BeginName.m_Result;a ++)
		for(int b = 0;b < EndName.m_Result;b ++)
			for(int c = 0;c < AllRoad[BeginName.m_IndexRoad[a]].Num;c ++)
				for(int d = 0;d < AllRoad[EndName.m_IndexRoad[b]].Num;d ++)
				{
					StationName = "乘车路线是:\r\n";
					temp = " ";
					if(strcmp(AllRoad[BeginName.m_IndexRoad[a]].name[c],AllRoad[EndName.m_IndexRoad[b]].name[d]) == 0)//寻找起始线路和终止线路的共同点
					{
						PathLength = abs(BeginName.m_IndexName[a] - c) + abs(EndName.m_IndexName[b] - d);
						temp.Format("坐%s\r",BeginName.m_TruckName[a]);
						StationName += temp;
						if(BeginName.m_IndexName[a] < c)
						{
							for(int e = BeginName.m_IndexName[a];e <= c;e ++)
							{
								if(e == c)
									temp.Format("%s",AllRoad[BeginName.m_IndexRoad[a]].name[e]);
								else
									temp.Format("s-",AllRoad[BeginName.m_IndexRoad[a]].name[e]);
								StationName += temp;
							}
						}
						else
						{
							for(int f = BeginName.m_IndexName[a];f >= c;f --)
							{
								if(f == c)
									temp.Format("%s",AllRoad[BeginName.m_IndexRoad[a]].name[f]);
								else
									temp.Format("%s-",AllRoad[BeginName.m_IndexRoad[a]].name[f]);
								StationName += temp;
							}
						}
						temp.Format("\r\n换%s\r\n",EndName.m_TruckName[b]);
						StationName += temp;
						if(EndName.m_IndexName[b] > d)
						{
							for(int g = d;g <= EndName.m_IndexName[b];g ++)
							{
								if(g == EndName.m_IndexName[b])
									temp.Format("%s",AllRoad[EndName.m_IndexRoad[b]].name[g]);
								else
									temp.Format("%s-",AllRoad[EndName.m_IndexRoad[b]].name[g]);
								StationName += temp;
							}
						}
						else
						{
							for(int h = d;h >= EndName.m_IndexName[b];h --)
							{
								if(h == EndName.m_IndexName[b])
									temp.Format("%s",AllRoad[EndName.m_IndexRoad[b]].name[h]);
								else
									temp.Format("%s-",AllRoad[EndName.m_IndexRoad[b]].name[h]);
								StationName += temp;
							}
						}
						result ++;
						WayLong[CheckWay] = PathLength;
						Way[CheckWay].Format("路程是坐%s,从%s起坐%d站,到%s,换%s坐%d站,到终点%s\r\n",AllRoad[BeginName.m_IndexRoad[a]].TruckName,BeginName.m_Name,abs(BeginName.m_IndexName[a] - c),AllRoad[EndName.m_IndexRoad[b]].name[d],AllRoad[EndName.m_IndexRoad[b]].TruckName,abs(EndName.m_IndexName[b] - d),EndName.m_Name);
						Way[CheckWay] += StationName;
						CheckWay ++;
						check = true;
					}
				}
				if(check)
					ChoseShortestWay();
				else
					ThirdCheck();
			
}
//三次查询函数
void CRoadDlg::ThirdCheck()
{
	check = false;
	for(int a = 0;a < BeginName.m_Result;a ++)
		for(int b = 0;b < EndName.m_Result;b ++)
			for(int way = 0; way < NUM;way ++)//遍历所有路线名的记录
			{
				if(way == BeginName.m_IndexRoad[a])continue;
				if(way == EndName.m_IndexRoad[b])continue;
				for(int numbegin = 0;numbegin < AllRoad[way].Num;numbegin ++)//遍历所有车站名
				{
					for(int c = 0;c < AllRoad[BeginName.m_IndexRoad[a]].Num;c ++)
					{
						if(strcmp(AllRoad[BeginName.m_IndexRoad[a]].name[c],AllRoad[way].name[numbegin]) == 0)//如果找到起始线路与中间线路有共同点,则找终止线路与中间线路是否有公共点
						{
							for(int numend = 0;numend < AllRoad[way].Num; numend ++)
								for(int d = 0;d < AllRoad[EndName.m_IndexRoad[b]].Num;d ++)
								{
									if(strcmp(AllRoad[EndName.m_IndexRoad[b]].name[d],AllRoad[way].name[numend]) == 0)//找到既与起始线路又与终止线路有共通站的中间站
									{
										Way[CheckWay].Format("坐%s,从%s坐%d站到%s,再换%s,坐%d站到%s,再换%s坐%d站到终点%s",AllRoad[BeginName.m_IndexRoad[a]].TruckName,BeginName.m_Name,abs(BeginName.m_IndexName[a] - c),AllRoad[way].name[numbegin],AllRoad[way].TruckName,abs(numbegin - numend),AllRoad[way].name[numend],AllRoad[EndName.m_IndexRoad[b]].TruckName,abs(EndName.m_IndexName[b] - d),EndName.m_Name);
										WayLong[CheckWay] = abs(BeginName.m_IndexName[a] - c) + abs(numbegin - numend) + abs(EndName.m_IndexName[b] - d);
										CheckWay ++;
										check = true;
									}
								}
						}
					}
				}
			}
			if(check)
				ChoseShortestWay();
			else AfxMessageBox("没有找到路线!");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -