📄 roaddlg.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 + -