电子地图信息管理系统!!!
刚刚完成实训
三天的时间完成了电子地图管理系统
遇到不少困难但最后还是完成了项目
功能包括:读取dat文件,添加道路信息,五种排序算法,两种检索算法,更新数据文件,
自动比较不同排序算法性能
还有不少不足,日后慢慢改善
参考代码:C语言实现
不bb了,上代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<string.h>
#include<Windows.h>
//宏函数处理二进制数据
#define MCGETCHAR(data) (*((char *)(data)))
#define MCGETSHORT(data) ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff )))
#define MCGETLONG(data) ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )
#define MCGET3BN(data) ( ( ((unsigned long)MCGETCHAR((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+1))&0x0000ffff ) )
#define Length 99999
using namespace std;
static int sizecount = 0;//记录道路记录条数
static int sizecount2 = 0;//记录道路记录条数/用于性能分析算法
int mark1 = 0;//标记是否读取过文件
int mark2 = 0;//标记是否完成过排序
static int Sort_Time[5][2];//存放排序所花费时间——格式:Sort_Time[s][ms]
class RoadRecord //定义道路信息的类
{
private:
short int InfoSize; //信息尺寸2byte
long int LinkID; //4byte
short NameSize; //道路名字大小2byte
/*NodeInfo : 4byte*/
int DispClass; // 分类番号0~3
int Brunch; // 分叉数量4~6
int NameFlag; // 有无名字的标志7
char RoadName[20]; // 道路名字8~31
public:
/*运算符> < = <= >=的重载*/
int operator >(const RoadRecord &x)
{
if (LinkID > x.LinkID)
return 1;
else
return 0;
}
int operator <(const RoadRecord &x)
{
if (LinkID < x.LinkID)
return 1;
else
return 0;
}
int operator<=(const RoadRecord &x)
{
if (LinkID <= x.LinkID)
return 1;
else
return 0;
}
int operator>=(const RoadRecord &x)
{
if (LinkID >= x.LinkID)
return 1;
else
return 0;
}
/*赋值运算符重载,用于交换类对象成员数据*/
RoadRecord operator =(const RoadRecord &c)
{
InfoSize = c.InfoSize;
LinkID = c.LinkID;
NameSize = c.NameSize;
DispClass = c.DispClass;
Brunch = c.Brunch;
NameFlag = c.NameFlag;
memcpy(RoadName, c.RoadName, 20);
return *this;
}
/*对象和整型数据的运算符重载*/
bool operator==(int x)
{
if (this->LinkID == x)
return true;
else
return false;
}
bool operator>(int x)
{
if (this->LinkID > x)
return true;
else
return false;
}
bool operator<(int x)
{
if (this->LinkID < x)
return true;
else
return false;
}
/**************************************************************************************
* Functionname:RoadRecord::disp *
* Function Description:显示类对象成员数据 *
* Date:2019/11/12 *
**************************************************************************************/
void disp()
{
cout << "# LinkID=" << LinkID << '\t';
cout << " NameFlag=" << NameFlag << '\t';
cout << "Brunch=" << Brunch << '\t';
cout << " DispClass=" << DispClass << '\t';
if (NameFlag == 1)
cout << "RoadName=" << RoadName << '\t' << "#" << endl;
else
cout << "RoadName=" << "无 #" << endl;
}
operator long int()//变换构造函数获取LinkID
{
return LinkID;
}
friend void Add_Record(RoadRecord rr[]);
friend int Read_File_Data(RoadRecord rr[]);
friend int Temporary_Read(RoadRecord rr[]);
friend void Sort(RoadRecord A[], int N);
friend int Write_Result(int j, int count[], RoadRecord rr[]);
friend int Search_Data(RoadRecord rr[]);
friend int Update(RoadRecord rr[]);
};
/*获取系统当前时间*/
void Gettime()
{
SYSTEMTIME sys;
GetLocalTime(&sys);
printf("%02d:%02d:%02d.%03d\n", sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
}
/**************************************************************************************
* Functionname:Read_File_Data *
* Function Description:读取二进制文件,并将其解析在文本文档里 *
* Date:2019/11/12 *
* 参考C语言代码转化为C++代码编译成功 *
**************************************************************************************/
int Read_File_Data(RoadRecord rr[])
{
int m;//用于处理4byte的NodeInfo
sizecount = 0;//初始化数组长度避免溢出
char actotalsize[2];//利用字符数组获取需读出文件的长度
char aclinkid[4];
char acroadnamesize[2];
char acNodeInfo[4];
unsigned short ustotalsize;//us/ul变量存放处理后的二进制数据并赋给对象数组
unsigned long ullinkid;
unsigned short usroadnamesize;
//ifstream inFile("d:\\new_GTBL.dat", ios::in | ios::binary);//用于判断更新文件是否成功
ifstream inFile("d:\\GTBL.dat", ios::in | ios::binary);
ofstream outFile("d:\\GTBL.txt", ios::out);
cout << "正在打开文件D:\\GTBL.dat以及创建文件D:\\GTBL.txt..." << endl;
if (!inFile) {//检查GTBL.dat是否打开成功
cout << "找不到文件GTBL.dat!" << endl;
return 0;
}
if (!outFile) {//检查GTBL.txt是否打开/创建成功
cout << "找不到文件GTBL.txt!" << endl;
return 0;
}
cout << "正在将地图信息写入GTBL.txt..." << endl;
while (inFile.read(actotalsize, sizeof(actotalsize))) {
/*读文件操作,sizeof(字符数组)来获取需读入的位长*/
inFile.read(aclinkid, sizeof(aclinkid));
inFile.read(acroadnamesize, sizeof(acroadnamesize));
inFile.read(acNodeInfo, sizeof(acNodeInfo));
/*调用宏函数 , 将字符串信息转化为数值类型*/
ustotalsize = MCGETSHORT(actotalsize);
ullinkid = MCGETLONG(aclinkid);
usroadnamesize = MCGETSHORT(acroadnamesize);
/*赋值给对象数组*/
rr[sizecount].InfoSize = ustotalsize;
rr[sizecount].LinkID = ullinkid;
rr[sizecount].NameSize = usroadnamesize;
/*利用m处理NodeInfo的二进制数据以获得Node情报并赋值*/
m = (int)acNodeInfo[3] & 255;
rr[sizecount].DispClass = m & 15;
rr[sizecount].Brunch = (m & 112) / 16;
rr[sizecount].NameFlag = (m & 128) / 128;
/*获取道路名称(ustotalsize-12为道路名称所占byte长)*/
inFile.read(rr[sizecount].RoadName, ustotalsize - 12);
/*将道路数据写入创建的txt文本文档*/
outFile << "#" << '\t' << "LinkID=" << rr[sizecount].LinkID << '\t';
outFile << "flag=" << rr[sizecount].NameFlag << '\t';
outFile << "brunch=" << rr[sizecount].Brunch << '\t';
outFile << "dispclass=" << rr[sizecount].DispClass << '\t';
if (rr[sizecount].NameFlag == 1)
outFile << "Roadname=1=" << rr[sizecount].RoadName + 4 << '\t' << "#" << endl;
else
outFile << "Roadname=1=" << '\t' << "#" << endl;
/*if(rr[sizecount].NameFlag==1)
cout << rr[sizecount].InfoSize << "\t" << rr[sizecount].LinkID << "\t"
<< rr[sizecount].NameSize << "\t" << rr[sizecount].dispclass << "\t"
<< rr[sizecount].brunch << "\t" << rr[sizecount].NameFlag << "\t" << rr[sizecount].RoadName << endl;
else
cout << rr[sizecount].InfoSize << "\t" << rr[sizecount].LinkID << "\t"
<< rr[sizecount].NameSize << "\t" << rr[sizecount].dispclass << "\t"
<< rr[sizecount].brunch << "\t" << rr[sizecount].NameFlag << endl;*/
sizecount++;
}
cout << "数据读取成功!" << endl;
mark1++;
/*关闭文件*/
inFile.close();
outFile.close();
system("pause");
return 0;
}
/**************************************************************************************
* Functionname:Temporary_Read *
* Function Description:读取二进制文件存入类对象(暂时供排序性能比较使用) *
* Date:2019/11/14 *
* 参考C语言代码转化为C++代码编译成功 *
**************************************************************************************/
int Temporary_Read(RoadRecord rr[])
{
int m;//用于处理4byte的NodeInfo
sizecount2 = 0;//初始化数组长度避免溢出
char actotalsize[2];//利用字符数组获取需读出文件的长度
char aclinkid[4];
char acroadnamesize[2];
char acNodeInfo[4];
unsigned short ustotalsize;//us/ul变量存放处理后的二进制数据并赋给对象数组
unsigned long ullinkid;
unsigned short usroadnamesize;
//ifstream inFile("d:\\new_GTBL.dat", ios::in | ios::binary);//用于判断更新文件是否成功
ifstream inFile("d:\\GTBL.dat", ios::in | ios::binary);
if (!inFile) {//检查GTBL.dat是否打开成功
cout << "找不到文件GTBL.dat!" << endl;
return 0;
}
while (inFile.read(actotalsize, sizeof(actotalsize))) {
/*读文件操作,sizeof(字符数组)来获取需读入的位长*/
inFile.read(aclinkid, sizeof(aclinkid));
inFile.read(acroadnamesize, sizeof(acroadnamesize));
inFile.read(acNodeInfo, sizeof(acNodeInfo));
/*调用宏函数 , 将字符串信息转化为数值类型*/
ustotalsize = MCGETSHORT(actotalsize);
ullinkid = MCGETLONG(aclinkid);
usroadnamesize = MCGETSHORT(acroadnamesize);
/*赋值给对象数组*/
rr[sizecount2].InfoSize = ustotalsize;
rr[sizecount2].LinkID = ullinkid;
rr[sizecount2].NameSize = usroadnamesize;
/*利用m处理NodeInfo的二进制数据以获得Node情报并赋值*/
m = (int)acNodeInfo[3] & 255;
rr[sizecount2].DispClass = m & 15;
rr[sizecount2].Brunch = (m & 112) / 16;
rr[sizecount2].NameFlag = (m & 128) / 128;
/*获取道路名称(ustotalsize-12为道路名称所占byte长)*/
inFile.read(rr[sizecount2].RoadName, ustotalsize - 12);
sizecount2++;
}
/*关闭文件*/
inFile.close();
return 0;
}
/**************************************************************************************
* Functionname:add_record *
* Function Description:添加道路信息至对象数组尾部 *
* Date:2019/11/13 *
**************************************************************************************/
void Add_Record(RoadRecord rr[])
{
char opt = 'Y';
while (opt != 'N') {
cout << "开始添加道路信息!" << endl;
cout << "请依次输入InfoSize/LinkID/NameSize/Class/Brunch/Flag/Name:" << endl;
cin >> rr[sizecount].InfoSize >> rr[sizecount].LinkID >> rr[sizecount].NameSize >>
rr[sizecount].DispClass >> rr[sizecount].Brunch >>
rr[sizecount].NameFlag >> rr[sizecount].RoadName;
sizecount++;
cout << "添加完成!" << endl;
cout << "是否继续添加道路信息?(Y/N)" << endl;
cin >> opt;
}
cout << "返回功能菜单..." << endl;
system("pause");
}
//冒泡排序
void Bubble_Sort(RoadRecord A[], int N)
{
int i, j;
bool change;//记录是否还有交换操作,如果没有则排序结束
RoadRecord temp;
for (i = N - 1, change = true; i >= 1 && change; --i)//外循环
{
change = false;
for (j = 0; j < i; ++j)//内循环
if (A[j] > A[j + 1])
{
temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
change = true;
}
}
cout << "冒泡排序完成!" << endl;
}
//直接插入排序
void Insertion_Sort(RoadRecord A[], int N)
{
int i, j;
RoadRecord temp;
for (i = 1; i < N; i++)
{
temp = A[i];
for (j = i - 1; j >= 0 && temp < A[j]; j--)
{
if (A[j - 1] > temp)
A[j + 1] = A[j];//比当前元素小的往后移动
}
A[j + 1] = temp;//将当前元素插入到合适的位置
}
cout << "插入排序完成!" << endl;
}
//希尔排序
void Shell_Sort(RoadRecord A[], int N)
{
int i, j, Increment;
RoadRecord temp;
for (Increment = N / 2; Increment > 0; Increment /= 2)
for (i = Increment; i < N; i++) {
temp = A[i];
for (j = i; j >= Increment; j -= Increment)
if (temp < A[j - Increment])
A[j] = A[j - Increment];
else
break;
A[j] = temp;
}
cout << "希尔排序完成!" << endl;
}
//归并排序
void Merge(RoadRecord A[], RoadRecord temp[], int lpos, int rpos, int rightend)
{
int i, leftend, num, tempPos;
leftend = rpos - 1;
tempPos = lpos;
num = rightend - lpos + 1;
while (lpos <= leftend && rpos <= rightend)
if (A[lpos] <= A[rpos])
temp[tempPos++] = A[lpos++];
else
temp[tempPos++] = A[rpos++];
while (lpos <= leftend)
temp[tempPos++] = A[lpos++];
while (rpos <= rightend)
temp[tempPos++] = A[rpos++];
for (i = 0; i < num; i++, rightend--)
A[rightend] = temp[rightend];
}
void MSort(RoadRecord A[], RoadRecord temp[], int left, int right)
{
int center;
if (left < right)
{
center = (left + right) / 2;
MSort(A, temp, left, center);
MSort(A, temp, center + 1, right);
Merge(A, temp, left, center + 1, right);
}
}
void Merge_Sort(RoadRecord A[], int N)
{
RoadRecord *temp;
temp = (RoadRecord *)malloc(N * sizeof(RoadRecord));
if (temp != NULL)
{
MSort(A, temp, 0, N - 1);
free(temp);
}
else
cout << "No more Space" << endl;
cout << "归并排序完成!" << endl;
}
//基数排序
void Base_Sort(RoadRecord A[], int N)
{
//申请一个临时数组的内存
RoadRecord *temp = (RoadRecord *)malloc(N * sizeof(RoadRecord));
for (int i = 0; i < N; i++)
if (A[i] > 80000)
temp[0] = A[i];
else
temp[A[i]] = A[i];//这里要调用变换构造函数
//将数据写回原来数组
A[N - 1] = temp[0];//temp[0]是最大的数据妨到最后
for (int i = 1; i < N; i++)
A[i - 1] = temp[i];
//程序调用结束将释放临时数组内存
free(temp);
cout << "基数排序完成!" << endl;
}
//快速排序
/*void Quick_Sort(RoadRecord A[], int low, int high)
{
if (low < high){
int i = low, j = high;
RoadRecord pivokey = A[low];
while (i < j){
while (i < j && A[j] >= pivokey) j--;
if (i < j)
A[i++] = A[j];
while (i < j && A[i] <= pivokey) i++;
if (i < j)
A[j--] = A[i];
}
A[i] = pivokey;
Quick_Sort(A, low, i - 1);
Quick_Sort(A, i + 1, high);
}
}*/
/**************************************************************************************
* Functionname:Sort *
* Function Description:排序算法程序,并获取排序时间 *
* Date:2019/11/14 *
**************************************************************************************/
void Sort(RoadRecord A[], int N)
{
SYSTEMTIME sys1, sys2;//定义开始时时间对象和完成后时间对象
int select;//定义选择变量并初始化
cout << "请选择排序方法:" << endl;
cout << "1.Bubble_Sort" << endl << "2.Insert_Sort" << endl << "3.Shell_Sort"
<< endl << "4.Merge_Sort" << endl << "5.Base_Sort" << endl << "0.退出搜索模块" << endl;
cout << "请选择:" << endl;
cin >> select;
while (select < 1 || select>5) {//处理输入选择变量错误的情况
cout << "输入有误!请重新输入:" << endl;
cin >> select;
}
if (select != 0) {
GetLocalTime(&sys1);//获取开始时间
printf("开始时间为:%02d:%02d:%02d.%03d\n",
sys1.wHour, sys1.wMinute, sys1.wSecond, sys1.wMilliseconds);//显示开始时间
}
switch (select)
{
case 1:
cout << "正在进行冒泡排序中..." << endl;
Bubble_Sort(A, N);
break;
case 2:
cout << "正在进行直接插入排序中..." << endl;
Insertion_Sort(A, N);
break;
case 3:
cout << "正在进行希尔排序中..." << endl;
Shell_Sort(A, N);
break;
case 4:
cout << "正在进行归并排序中..." << endl;
Merge_Sort(A, N);
break;
case 5:
cout << "正在进行基数排序中..." << endl;
Base_Sort(A, N);
break;
case 0:
break;
}
if (select != 0) {
GetLocalTime(&sys2);//获取结束时间
printf("结束时间为:%02d:%02d:%02d.%03d\n",
sys2.wHour, sys2.wMinute, sys2.wSecond, sys2.wMilliseconds);//显示结束时间
}
//计算排序过程花费时间(将分秒毫秒转换成秒单位显示)
if (select != 0) {
if (sys2.wMilliseconds < sys1.wMilliseconds) {
if (sys2.wSecond < sys1.wSecond) {
cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond) - 1
<< "." << sys1.wMilliseconds - sys2.wMilliseconds << "秒" << endl;
}
else {
cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond) - 1
<< "." << sys1.wMilliseconds - sys2.wMilliseconds << "秒" << endl;
}
}
else {
if (sys2.wSecond < sys1.wSecond) {
cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond)
<< "." << sys2.wMilliseconds - sys1.wMilliseconds << "秒" << endl;
}
else {
cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond)
<< "." << sys2.wMilliseconds - sys1.wMilliseconds << "秒" << endl;
}
}
}
cout << "已退出排序模块!" << endl;
mark2++;
system("pause");
}
/**************************************************************************************
* Functionname:Write_Result *
* Function Description:将检索到的大于5条的道路信息写入txt文本文档 *
* Date:2019/11/13 *
**************************************************************************************/
int Write_Result(int j, int count[], RoadRecord rr[])
{
int c;//暂时存放需显示对象数组下标
ofstream outFile("d:\\search_flie.txt", ios::out);//创建文件
if (!outFile) {//检查search_file.txt是否打开/创建成功
cout << "找不到search_file.txt!" << endl;
return 0;
}
cout << "正在写入文件..." << endl;
for (int i = 0; i < j; i++) {
c = count[i];
outFile << "#" << '\t' << "LinkID=" << rr[c].LinkID << '\t';
outFile << "flag=" << rr[c].NameFlag << '\t';
outFile << "brunch=" << rr[c].Brunch << '\t';
outFile << "dispclass=" << rr[c].DispClass << '\t';
if (rr[c].NameFlag == 1)
outFile << "Roadname=1=" << rr[c].RoadName + 4 << '\t' << "#" << endl;
else
outFile << "Roadname=1=" << '\t' << "#" << endl;
}
cout << "已写入文件search_file.txt" << endl;
outFile.close();
return 0;
}
//折半查找
int Half_Search(RoadRecord A[], int N, int target)
{
int low, high, mid;
//初始化low和high
low = 0; high = N - 1;
mid = (low + high) / 2;
while (low <= high)
{
if (A[mid] == target)
return mid;
if (A[mid] < target)//目标在右边
low = mid + 1;
else//目标在左边
high = mid - 1;
//更新mid
mid = (low + high) / 2;
}
cout << "未找到目标LinkID!" << endl;
return 0;
}
/**************************************************************************************
* Functionname:Search_Data *
* Function Description:根据用户需要检索的信息对道路信息进行检索 *
* 小于5条直接显示/大于5条写入文件search_file.txt *
* Date:2019/11/12 *
**************************************************************************************/
int Search_Data(RoadRecord rr[])
{
int select;
char opt = 'Y';
int i, j, k, c;//i控制循环 j记录符合要求的信息条数 k作为count数组的下标计数器 c用于显示检索到的数据
while (opt != 'N') {
cout << "请选择需要搜索的信息:(小于等于五条直接显示,大于五条将写入文件D:\\search_flie.txt)" << endl;
cout << "1.LinkID" << endl << "2.DispClass" << endl << "3.Brunch" << endl << "4.RoadName" << endl;
cout << "0.退出搜索系统" << endl;
cout << "请选择需要搜索的信息:" << endl;
cin >> select;//功能选择
if (select == 1) {//检索LinkID(因LinkID有序,使用折半查找)
int LI;
cout << "请输入需要搜索的LinkID(1-7位整数):" << endl;
cin >> LI;
/*for (i = 0; i < sizecount; i++) {
if (rr[i].LinkID == LI) {
cout << "搜索成功!" << endl;
rr[i].disp();
}
}*/
int f = Half_Search(rr, sizecount, LI);
if (f) {
rr[f].disp();
}
}
else if (select == 2) {//检索DispClass
int DC;
k = 0;
j = 0;
cout << "请输入需要搜索的DispClass:" << endl;
cin >> DC;
for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
if (rr[i].DispClass == DC) {
j++;
}
}
int *count = new int[j];//j个元素的数组用于存放符合条件的下标
for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
if (rr[i].DispClass == DC) {
count[k] = i;
k++;
}
}
if (j == 0) {
cout << "未找到符合要求的数据!" << endl;
}
else if (j <= 5) {//小于5个 直接显示
cout << "搜索成功!直接显示:" << endl;
for (i = 0; i < j; i++) {
c = count[i];
rr[c].disp();
}
}
else if (j > 5) {//大于5个 写入文件
cout << "搜索成功,结果大于5条!" << endl;
Write_Result(j, count, rr);
}
delete[]count;
}
else if (select == 3) {//检索Brunch
int BC;
k = 0;
j = 0;
cout << "请输入需要搜索的Brunch:" << endl;
cin >> BC;
for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
if (rr[i].Brunch == BC) {
j++;
}
}
int *count = new int[j];//j个元素的数组用于存放符合条件的下标
for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
if (rr[i].Brunch == BC) {
count[k] = i;
k++;
}
}
if (j == 0) {
cout << "未找到符合要求的数据!" << endl;
}
else if (j <= 5) {//小于5个 直接显示
cout << "搜索成功!直接显示:" << endl;
for (i = 0; i < j; i++) {
c = count[i];
rr[c].disp();
}
}
else if (j > 5) {//大于5个 写入文件
cout << "搜索成功,结果大于5条!" << endl;
Write_Result(j, count, rr);
}
delete[]count;
}
else if (select == 4) {//检索RoadName
char RN[20] = { 0 };
k = 0;
j = 0;
cout << "请输入需要搜索的RoadName:" << endl;
cin >> RN;
for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
if (rr[i].NameFlag == 0) {}
else if (strcmp(rr[i].RoadName + 4, RN) == 0) {
j++;
}
}
int *count = new int[j];//j个元素的数组用于存放符合条件的下标
for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
if (rr[i].NameFlag == 0) {}
else if (strcmp(rr[i].RoadName + 4, RN) == 0) {
count[k] = i;
k++;
}
}
if (j == 0) {
cout << "未找到符合要求的数据!" << endl;
}
else if (j <= 5) {//小于5个 直接显示
cout << "搜索成功!直接显示:" << endl;
for (i = 0; i < j; i++) {
c = count[i];
rr[c].disp();
}
}
else if (j > 5) {//大于5个 写入文件
cout << "搜索成功,结果大于5条!" << endl;
Write_Result(j, count, rr);
}
delete[]count;
}
else if (select == 0) {
cout << "退出检索模块!" << endl;
return 0;
}
cout << "是否继续检索信息?(Y/N)" << endl;
cin >> opt;
}
cout << "退出检索模块!" << endl;
system("pause");
return 0;
}
/**************************************************************************************
* Functionname:Update *
* Function Description:将增添好信息和排序完成的道路信息写入文件new_file.txt *
* Date:2019/11/13 *
**************************************************************************************/
int Update(RoadRecord rr[])
{
ofstream outFile("d:\\new_file.txt", ios::out);//创建txt文档存放更新后的道路数据
cout << "创建文件d:\\new_file.txt中..." << endl;
if (!outFile) {//检查new_file.txt是否打开/创建成功
cout << "ERROR!NO new_file.txt!" << endl;
return 0;
}
cout << "正在将更新数据写入文件..." << endl;
for (int i = 0; i < sizecount; i++) {//写入txt文本文档
outFile << "#" << '\t' << "LinkID=" << rr[i].LinkID << '\t';
outFile << "flag=" << rr[i].NameFlag << '\t';
outFile << "brunch=" << rr[i].Brunch << '\t';
outFile << "dispclass=" << rr[i].DispClass << '\t';
if (rr[i].NameFlag == 1)
outFile << "Roadname=1=" << rr[i].RoadName + 4 << '\t' << "#" << endl;
else
outFile << "Roadname=1=" << '\t' << "#" << endl;
}
cout << "更新成功!请前往d:\\new_file.txt查看更新结果!" << endl;
outFile.close();
system("pause");
/*char pc[60];
/*由于C++语言无法在读取txt文件的字符串时,设定遇到空格便结
束的功能只能设定读取的边界,这使将读取txt文件中字符并传入
dat文件中变得困难所以在本段程序中,使用了C语言的文件操作
errno_t err;
FILE *p2; //文件指针p2用于打开new_file文件
if ((err=fopen_s(&p2,"d:\\new_file.txt", "r") )!= NULL) {//打开文件new_file为更新文件提供数据
cout << "new_file.txt打开失败!" << endl;
return 0;
}
FILE *p3; //文件指针p3用来创建new_GTBL文件
if ((err=fopen_s(&p3,"d:\\new_GTBL.dat", "wb")) != NULL){//判断文件创建是否成功
cout << "new_GTBL.dat创建失败!" << endl;
return 0;
}
cout<<"文件更新中..."<<endl; //给出提示信息
for (int i = 0; i < sizecount; i++)
{
fread(pc, 56, 1, p2); //new_file文件信息->pc数组中
fwrite(pc, 56, 1, p3); //数组pc的信息->update二进制文件中
}
cout<<"文件更新成功!"<<endl<<"更新二进制数据存放在new_GTBL.dat文件中"<<endl;
fclose(p2);
fclose(p3);*/
return 0;
}
/**************************************************************************************
* Functionname:Analysis *
* Function Description:依次使用五种排序算法并自动比较排序时间 *
* Date:2019/11/13 *
**************************************************************************************/
void Analysis()
{
int i;
SYSTEMTIME sys1, sys2;
RoadRecord *A = new RoadRecord[Length];
cout << "正在依次进行五种不同排序算法并进行性能分析..." << endl;
for (i = 0; i < 5; i++) {//i控制每种排序的调用
GetLocalTime(&sys1);
switch (i) {
case 0:
Temporary_Read(A);//为临时类对象数组赋初值,来达到每次排序前数据序列都相同的目的
Bubble_Sort(A, sizecount2);
break;
case 1:
Temporary_Read(A);
Insertion_Sort(A, sizecount2);
break;
case 2:
Temporary_Read(A);
Shell_Sort(A, sizecount2);
break;
case 3:
Temporary_Read(A);
Merge_Sort(A, sizecount2);
break;
case 4:
Temporary_Read(A);
Base_Sort(A, sizecount2);
break;
}
GetLocalTime(&sys2);
if (sys2.wMilliseconds < sys1.wMilliseconds) {
if (sys2.wSecond < sys1.wSecond) {//为排序时间二维数组赋值
Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond)) - 1;
Sort_Time[i][1] = (sys1.wMilliseconds - sys2.wMilliseconds);
}
else {
Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond) - 1);
Sort_Time[i][1] = (sys1.wMilliseconds - sys2.wMilliseconds);
}
}
else {
if (sys2.wSecond < sys1.wSecond) {
Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond));
Sort_Time[i][1] = (sys2.wMilliseconds - sys1.wMilliseconds);
}
else {
Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond));
Sort_Time[i][1] = (sys2.wMilliseconds - sys1.wMilliseconds);
}
}
}
cout << "分析完成!" << endl;
cout << "*******算法性能比较*******" << endl;
cout << "Means" << '\t' << '\t' << "TIME" << endl;//显示性能比较结果
cout << "Bubble" << '\t' << '\t' << Sort_Time[0][0] << "." << Sort_Time[0][1] << "ms" << endl;
cout << "Insertion" << '\t' << Sort_Time[1][0] << "." << Sort_Time[1][1] << "ms" << endl;
cout << "Shell" << '\t' << '\t' << Sort_Time[2][0] << "." << Sort_Time[2][1] << "ms" << endl;
cout << "Merge" << '\t' << '\t' << Sort_Time[3][0] << "." << Sort_Time[3][1] << "ms" << endl;
cout << "Base" << '\t' << '\t' << Sort_Time[4][0] << "." << Sort_Time[4][1] << "ms" << endl;
cout << "**************************" << endl;
delete[]A;//释放内存
system("pause");
}
/**************************************************************************************
* Functionname:Menu *
* Function Description:设计菜单调用各模块算法 *
* Date:2019/11/14 *
**************************************************************************************/
void Menu(RoadRecord rr[])
{
int opt = 1;//选择变量
while (opt != 0) {
system("cls");
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
cout << "* -Welcome *" << endl;
cout << "* -to *" << endl;
cout << "* -电子地图管理系统- *" << endl;
cout << "*-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-*" << endl;
cout << "* 1.读取文件(D:\\GTBL.dat) *" << endl;
cout << "* 2.添加道路信息 *" << endl;
cout << "* 3.排序并显示算法性能(根据LinkID) *" << endl;
cout << "* 4.检索道路信息 *" << endl;
cout << "* 5.更新道路信息(D:\\new_file.txt) *" << endl;
cout << "* 6.排序算法性能分析 *" << endl;
cout << "* 0.退出系统 *" << endl;
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
cout << "请选择:" << endl;
cin >> opt;
switch (opt)
{
case 1:
Read_File_Data(rr);
break;
case 2:
if (mark1 == 0) {
cout << "请先读取文件!" << endl;
break;
}
Add_Record(rr);
break;
case 3:
if (mark1 == 0) {
cout << "请先读取文件!" << endl;
break;
}
Sort(rr, sizecount);
break;
case 4:
if (mark1 == 0 || mark2 == 0) {
cout << "请先读取文件并排序!" << endl;
break;
}
Search_Data(rr);
break;
case 5:
if (mark1 == 0 || mark2 == 0) {
cout << "请先读取文件并排序!" << endl;
break;
}
Update(rr);
break;
case 6:
Analysis();
break;
}
}
system("cls");
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* 已退出系统! *" << endl;
cout << "* 感谢您的使用! *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* *" << endl;
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
}
int main()
{
RoadRecord *dd = new RoadRecord[Length];//动态创建对象数组以防止stack overflow
/*设计打开系统的简单欢迎界面*/
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
for (int i = 0; i < 4; i++) {
Sleep(500);
cout << "* *" << endl;
}
Sleep(500);
cout << "* 系统加载中... *" << endl;
Sleep(500);
cout << "* 请稍等:) *" << endl;
for (int i = 0; i < 4; i++) {
Sleep(500);
cout << "* *" << endl;
}
Sleep(500);
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
Sleep(1000);
system("cls");
Menu(dd);
delete[]dd;
system("pause");
return 0;
}
如有错误,欢迎指点