校园导航系统——迪杰特斯拉算法

#include<iostream>
#include<string>
#include<fstream>
#include<Windows.h>
#include"stdio.h"
#include<ctype.h>
#include<conio.h>
#include<sstream>
using namespace std;
//最大值
#define INFINITY 32767
//管理员密码
string G_PIN;
//迪杰特斯拉算法的辅助数组
int have [12];
//存放景点信息
string info [12];
//最大顶点个数
#define MAX_V 30

//图
typedef struct
{
    char* vexs[MAX_V];       //顶点向量
    int arcs[MAX_V][MAX_V];//邻接矩阵
    int vexnum,arcnum;//图的当前顶点数和弧数
} MGraph;


//从txt文件读取信息
void read()
{
    ifstream in ("point.txt",ios::in);
    if(!in)
    {
        cerr << "Open \"point.txt\" error!"<<endl;
        exit(1);
    }
    int i = 0;
    while(in.eof()==0)
    {
        in >> info[i];
        //cout << info[i];
        i++;
    }
    in.close();
    ifstream inB ("G_PIN.txt",ios::in);
    inB >> G_PIN;
    in.close();
}
//将数据保存到txt文件中
void save()
{
    ofstream out("point.txt",ios::out);
    out.close();
    ofstream outA ("point.txt",ios::out);
    int i = 0;
    while(i<12)
    {
        outA << info[i] <<endl;
        i ++;
    }
    out.close();
    ofstream outB ("G_PIN.txt",ios::out);
    outB << G_PIN;
    outB.close();

}
//输入密码回显星号
string getPass()
{
    unsigned char c;
    string pass;
    int i = 0;
    while ((c=getch())!='\r')
    {
        if (isprint(c) &&  c!=' ')
        {
            pass += c;
            putchar('*');
        }
        else if (c=='\b')
        {
            pass += c;
            putchar('\b');
            putchar(' ');
            putchar('\b');
        }
    }
    putchar('\n');
    int len = pass.length();
    for(int j = 0; j<len; j++)
    {
        if(pass[j]=='\b')
        {
            pass.erase(j,1);
            pass.erase(j-1,1);
            j = 0;
            len = pass.length();
        }
    }
    return pass;
}
//密码验证(6-16位字符,数字和英文字符)
bool PIN_yanzheng(string pin)
{
    if(pin.length()<6 || pin.length()>16)
    {
        cout<<"位数不符合!在6-16位之间!"<<endl;
        return false;
    }
    else
    {
        for(int i = 0; i<pin.length(); i++)
        {
            if((pin[i]<'0') || (pin[i]>'z')||(pin[i]>'9'&&pin[i]<'A') || (pin[i]>'Z'&&pin[i]<'a'))
            {
                cout<<"只能包含数字和字母...."<<endl;
                return false;
            }
        }
        cout<<"密码合法..."<<endl;
        return true;
    }
}

//主菜单(1.管理员2.用户0.退出其余不合法)
void menu_main()
{ 
	cout<<"          ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※"<<endl;
	cout<<"          ※※※※                                          ※※※※"<<endl;
	cout<<"          ※※※※   欢迎使用中国海洋大学校园导航系统!      ※※※※"<<endl;
	cout<<"          ※※※※       请选择用户登录或者管理员登陆       ※※※※"<<endl;
	cout<<"          ※※※※           1   超级用户界面               ※※※※"<<endl;
	cout<<"          ※※※※           2   普通用户界面               ※※※※"<<endl;
	cout<<"          ※※※※           0    退出系统                  ※※※※"<<endl;
	cout<<"          ※※※※                                          ※※※※"<<endl;
	cout<<"          ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※"<<endl;
	cout<<"             选择一个功能(0-2):";
}
//景点菜单
void menu_point()
{
	
	printf("                                        ①西门                                 ");printf("\n");
	printf("                                        | \\                                   ");printf("\n");
	printf("                                        |   ②----③足球场                     ");printf("\n");
	printf("                                        |  体育馆  \\                          ");printf("\n");
	printf("    南区                                |           \\                         ");printf("\n");
	printf("    ⑩----⑾行远楼                     ⑥教学区       \\                       ");printf("\n");
	printf("          |                            / \\ \\_         \\                     ");printf("\n");
	printf("          |                       ___/     \\  \\_      ④北区宿舍             ");printf("\n");
	printf("          |                   __/            \\   \\  /   \\_                  ");printf("\n");
	printf("          |           ______/                 ⑦--⑧食堂   ⑤校医院            ");printf("\n");
	printf("          |   ______/                      五子顶 /                            ");printf("\n");
	printf("          | /                                    /                             ");printf("\n");
	printf("          ⑿图书馆                              /                              ");printf("\n");
	printf("                                               /                               ");printf("\n");
	printf("                                              /                                ");printf("\n");
	printf("                                             /                                 ");printf("\n");
	printf("                                            /                                  ");printf("\n");
	printf("                                           /                                   ");printf("\n");
	printf("                                          ⑨东区                               ");printf("\n");
}
//管理员菜单
void G_menu()
{
	cout<<endl<<endl<<endl;
	cout<<"          \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl;
	cout<<"          \3\3\3\3\3\3        1  查看景点信息           \3\3\3\3\3\3"<<endl;
	cout<<"          \3\3\3\3\3\3        2  修改景点信息           \3\3\3\3\3\3"<<endl;
	cout<<"          \3\3\3\3\3\3        3  修 改 密  码           \3\3\3\3\3\3 "<<endl;
	cout<<"          \3\3\3\3\3\3        0  退 出  系 统           \3\3\3\3\3\3"<<endl;
	cout<<"          \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl;
	cout<<"           请选择一个功能(0-3):";
}
//用户菜单(1.查询景点信息,2.查询最短路径0.退出系统,其余不合法)
void Y_menu()
{
	cout<<endl<<endl<<endl<<endl<<endl;
	cout<<"                     \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl;
	
	cout<<"                     \3\3\3\3\3\3\3  1   查询最短路径   \3\3\3\3\3\3\3"<<endl;
	cout<<"                     \3\3\3\3\3\3\3  2   查询景点信息   \3\3\3\3\3\3\3"<<endl;
	cout<<"                     \3\3\3\3\3\3\3  0   退 出 系  统   \3\3\3\3\3\3\3"<<endl;
	cout<<"                     \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl;
	cout<<"      请选择一个功能(0-2):";
}


//查看景点信息
void viewThePoint()
{
	string num_str;
	int num;
	bool trail;
    cout <<"输入你想要查看的景点编号(1-12):"<<endl;
    do
    {
        cin >> num_str;
		trail =("1"!=num_str&&"2"!=num_str &&"3"!=num_str && "4"!=num_str &&"5"!=num_str &&"6"!=num_str&&"7"!=num_str &&"8"!=num_str&&"9"!=num_str&&"10"!=num_str &&"11"!=num_str &&"12"!=num_str);
        if(trail)
        {
            cout <<"输入正确的范围!"<<endl;
        }
        else
        {
			num = atoi(num_str.c_str());
            cout << info[num-1] <<endl;
        }

    }
    while(trail);
}
//管理员修改景点信息
void G_modifyThePoint()
{
	//stringstream ss;
	string num_str;
	string str;  
	int num;
	bool trail = false;	
	do
	{
    menu_point();
    cout <<"您想要修改哪个景点的信息(1-12)?"<<endl;    
	cin >> num_str;
	trail =("1"!=num_str&&"2"!=num_str &&"3"!=num_str && "4"!=num_str &&"5"!=num_str &&"6"!=num_str&&"7"!=num_str &&"8"!=num_str&&"9"!=num_str&&"10"!=num_str &&"11"!=num_str &&"12"!=num_str);
        if(trail)
        {
            cout << "输入有误,请重新输入,1-12范围的数字。"<<endl;
			Sleep(2000);
			system("cls");
        }

    } while(trail);
	num = atoi(num_str.c_str());
	cout <<"您要修改的信息为:"<<info[num-1]<<endl;	
    cout <<"请输入将要修改的信息内容:"<<endl;
    cin >> str;
	cout << "确认信息修改?(N/n(不修改),其余输入确认修改)"<<endl;
	string modify;
	cin >> modify;
	if(modify == "n" || modify =="N")
	{
		cout <<"信息未修改"<<endl;
		return ;
	}
	else
	{
	    info[num-1] = str;
		cout <<"信息修改成功!"<<endl;
	}	

}
//管理员验证
bool G_yanzheng()
{
    string pin;
    char x;
    int times=0;
    do
    {
        cout<<"请输入您的管理员密码"<<endl;
        pin = getPass();
        times++;
        if(pin == G_PIN)
        {
            cout<<"密码输入正确!"<<endl;
            return true;
        }
        else
        {
            cout<<"密码输入错误!您还有"<<3-times<<"次机会!"<<endl;
            if(times ==  3)
            {
                cout<<"您已经三次密码输入错误,不能继续输入密码!"<<endl;
                return false;
            }
            cout<<"是否继续输入密码?否(N/n)是按其余键"<<endl;
            cin >> x;
            if( 'n'==x || 'N'==x)
            {
                return false;
            }
        }
    }
    while(pin !=G_PIN && times<3);
    return false;
}
void G_change_PIN()
{
    cout<<"为了保证您的账号安全,请输入您的原密码..."<<endl;
    string PIN;
    //cin>>PIN;
    PIN = getPass();
    if(PIN !=G_PIN)
    {
        cout<<"对不起,您的密码输入不正确..."<<endl;
        return;
    }
    char x;
    string pin;
    string pin2;
    do
    {
        do
        {
            cout<<"请输入新密码(6-16位,数字和字母)..."<<endl;
            //cin>>pin;
            pin = getPass();
        }
        while(PIN_yanzheng(pin) == false);
        cout<<"请再次确认密码(6-16位,数字和字母)..."<<endl;
        //cin>>pin2;
        pin2=getPass();
        if(pin2 == pin)
        {
            G_PIN = pin;
        }
        else
        {
            cout<<"两次输入密码不一致,是否重新输入密码?是(任意字符),否(N/n)"<<endl;
            cin>>x;
            if(x=='n' || x=='N')
            {
                cout<<"您的密码未修改!谢谢您的使用!"<<endl;
                return;
            }
        }
    }
    while(pin !=pin2&& x!='n'&&x!='N');
    cout<<"正在操作中,请耐心等候..."<<endl;
    ofstream out("G_PIN.txt");
    out<<G_PIN<<endl;
    Sleep(2000);
    cout<<"您的密码已经修改成功!谢谢您的使用!"<<endl;
}
//用户验证
bool Y_yanzheng()
{
    return true;
}
//创建无向图
void createUDN(MGraph &G)
{
    int i = 0,j=0;
    G.vexnum = 12;
    G.arcnum = 13;
    G.vexs[0] = "西门";
    G.vexs[1] = "体育馆";
    G.vexs[2] = "风雨操场";
    G.vexs[3] = "北区宿舍";
    G.vexs[4] = "校医院";
    G.vexs[5] = "教学区";
    G.vexs[6] = "五子顶";
    G.vexs[7] = "食堂";
    G.vexs[8] = "东区";
    G.vexs[9] = "南区";
    G.vexs[10] = "行远楼";
    G.vexs[11] ="图书馆";
    for(i=0; i<G.vexnum; i++) //初始化路径长度
        for(j=0; j<G.vexnum; j++)
        {
            if(i==j)
                G.arcs[i][j]=0;
            else
                G.arcs[i][j]=INFINITY;
        }
    //为每一条边赋权
    G.arcs[9][10] =G.arcs[10][9] = 100;
    G.arcs[10][11] =G.arcs[11][10]=270;
    G.arcs[11][5] =G.arcs[5][11]=500;
    G.arcs[11][6]=G.arcs[6][11]=150;
    G.arcs[6][7] =G.arcs[7][6] = 70;
    G.arcs[0][5]=G.arcs[5][0]=200;
    G.arcs[0][1]=G.arcs[1][0]=100;
    G.arcs[1][2]=G.arcs[2][1]=130;
    G.arcs[2][3]=G.arcs[3][2]=200;
    G.arcs[3][7]=G.arcs[7][3]=110;
    G.arcs[5][7]=G.arcs[7][5]=250;
    G.arcs[3][4]=G.arcs[4][3]=120;
    G.arcs[7][8]=G.arcs[8][7]=550;

}
//迪杰特斯拉算法
void Djtsl(MGraph &G,int v0,int p[MAX_V][MAX_V],int d[])
{
    //迪杰斯特拉发求最短路径
    int v,w,i,j,min;
    int final[MAX_V];
    int k=1;
    for(v=0; v<G.vexnum; ++v)
    {
        //初始化
        final[v]=0;
        d[v]=G.arcs[v0-1][v];
        for(w=0; w<G.vexnum; ++w)
            p[v][w]=0;
        if(d[v]<INFINITY)
        {
            p[v][v0-1]=1;
            p[v][v]=1;
        }
    }
    d[v0-1]=0;
    final[v0-1]=1;
    have[0]=v0-1;
    for(i=1; i<G.vexnum; ++i)
    {
        //其余的vexnum-1个顶点
        min=INFINITY;
        for(w=0; w<G.vexnum; ++w)
            if(!final[w])
                if(d[w]<min) //如有W点离更近
                {
                    v=w;
                    min=d[w];
                }
        final[v]=1;
        have[k]=v;
        k++;
        for(w=0; w<G.vexnum; ++w) //更新当前最短路径及距离
            if(!final[w]&&(min+G.arcs[v][w]<d[w]))
            {
                d[w]=min+G.arcs[v][w];
                for(j=0; j<G.vexnum; j++)
                    p[w][j]=p[v][j];
                p[w][w]=1;
            }
    }
}
//输入两点求最短路径
void shortPath()
{
	stringstream ss;
	string num_v0;
	string num_end;
	bool trail_v0 ;	
    bool trail_end;
	
	MGraph G;
    createUDN(G);
    int v0,i,end;
    int P[MAX_V][MAX_V];
    int D[MAX_V];

	    do
		{ 
			cout <<"请输入起点(1-12):";
	    	cin >> num_v0;
			trail_v0=("1"!=num_v0&&"2"!=num_v0&&"3"!=num_v0&& "4"!=num_v0 &&"5"!=num_v0 &&"6"!=num_v0&&"7"!=num_v0 &&"8"!=num_v0&&"9"!=num_v0&&"10"!=num_v0 &&"11"!=num_v0 &&"12"!=num_v0);
			if(trail_v0)
			{
				cout << "请正确输入起点(1-12)!"<<endl;
			}
	
		}while(trail_v0);
		do
		{ 
			cout <<"请输入终点(1-12):";
	    	cin >> num_end;
			trail_end=("1"!=num_end&&"2"!=num_end &&"3"!=num_end && "4"!=num_end &&"5"!=num_end &&"6"!=num_end&&"7"!=num_end &&"8"!=num_end&&"9"!=num_end&&"10"!=num_end &&"11"!=num_end &&"12"!=num_end);
			if(trail_end)
			{
				cout << "请正确输入终点(1-12)!"<<endl;
			}
	
		}while(trail_end);
	    


	v0 = atoi(num_v0.c_str());
	end = atoi(num_end.c_str());

    Djtsl(G,v0,P,D);
    cout << "最短路径是:"<<endl;
    for(i=0; i<G.vexnum; i++)
    {
        if(P[end-1][have[i]]==1)
            cout << "-->"<<G.vexs[have[i]];

    }
    cout << "路径长度是:"<<D[end -1] <<endl;
}
void main()
{
    system("color 37");

    string choice_main;
    string Y_choice;
    string G_choice;
    bool sign;//登录是否成功的标志
    read();
    do
    {
        menu_main();
        cin>>choice_main;
        if(choice_main=="0")
        {
            cout<<"正在关闭系统,请稍后..."<<endl;
            Sleep(2000);
            return ;
        }

        else if(choice_main == "1")
        {
            sign =G_yanzheng();
            if(sign == false)
            {
                cout<<"登录失败!系统将在三秒内关闭!"<<endl;
                Sleep(2000);
                save();
                return;
            }
            else
            {
                cout<<"登陆成功!"<<endl;
                Sleep(2000);
                system("cls");
                do
                {
                    G_menu();
                    cin>>G_choice;
                    if(G_choice == "1")
                    {
                        menu_point();
                        viewThePoint();
                    }
                    else if(G_choice =="2")
                    {
                        G_modifyThePoint();
                    }
                    else if(G_choice == "3")
                    {
                        G_change_PIN();
                    }
                    else if(G_choice == "0")
                    {
                        cout<<"正在退出系统..."<<endl;
                    Sleep(2000);
                    save();
                    return;              
                    }
                    else
                    {
                        cout<< "请正确输入!" <<endl;
                        Sleep(2000);
                        system("cls");
                    }
                    system("pause");
                    system("cls");
                }
                while(G_choice!="0");
            }
        }
        else if(choice_main == "2")
        {	
			
			Sleep(2000);
		    system("cls");

            do
            {
                Y_menu();
                cin>>Y_choice;
				
                if(Y_choice == "0")
                {
                    cout<<"正在退出系统..."<<endl;
                    Sleep(2000);
                    save();
                    return;
                }			
                else if(Y_choice =="1")
                {  
					

                    menu_point();
                    shortPath();
                }
                else if(Y_choice == "2")
                {
					
                    menu_point();
                    viewThePoint();
                }


                else
                {
                    cout<<"请您正确选择功能"<<endl;
					
                }

                system("pause");
                system("cls");
            }
            while(Y_choice!="0");
        }
        else
        {
            cout <<"请正确选择"<<endl;
            Sleep(2000);
            system("cls");
        }
    }
    while(choice_main !="2" && choice_main !="1");
}

实现简单的查询,各风景的查询,调用各函数,实现课程设计的目标。其中包含三个功能,一个是直接进入导航系统,利用主函数中已有的数据,进行查询:一个是进行创建数据,本程序中初始数据为农大的导航数据,如果需要也可以自己建立一个;最后一个是退出功能。设计该函数的目的是为了能够多次得应用dijkstra函数进行查询最短路径。同时该函数可以列出各景点的代号和对应的名称,这样大家只要输入代号就行了。方便进行查询。下面分别描述这些函数,建立它们函数原型。 1、主函数 函数原型:void main(void) 功 能:控制程序。 参 数:void 返 回 值:void 要 求:管理菜单命令并完成初始化。 2、菜单选择和处理函数 函数原型:int menu() 功 能:处理选择的菜单命令并接收用户选择的命令代码。 参 数:int 返 回 值:int 工作方式:返回命令代码的整数值,根据命令,调用相应函数。 要 求:只允许选择规定键,如果输入不合要求,则提醒用户重新输入。 3、建立邻接矩阵函数 函数原型:void createadj() 功 能:重新建立一个学生信息的记录。 参 数:void 返 回 值:void 工作方式:在需要的时候就可以有主菜单中调用 void createadj()函数。 要 求:必需输入信息记录,然后才能调用出search()函数进行查询。 4、dijkstra函数 函数原型:void dijkstra(intx,inty) 功 能:求两点间的最短路径 参 数:void 返 回 值:void 工作方式: 该函数被其它一些函数调用。 5、结束程序 函数原型:int Exit() 功 能:使程序正常结束运行 参 数:int 返 回 值:1 工作方式:在操作都完成后,可以调用int Exit()函数,使函数最终返回 1 运行exit(1),程序正常结束。 要 求:运行Exit()函数后可以选择是否要保存,选择y则先保存再返 回1值;如果选择n直接返回1值。详细的程序设计应从下到上,在本设计中就要先设计createadj函数;然后设计dijkstra函数;接着是search函数;menu函数;最后才是main函数。如此设计能大大提升设计速度,因为从下往上使编程时的高试过程简单许多,而做课程设计花费时间最多的就是调试过程。对于各函数的详细设计,各函数的N—S图如下: (1)Createadj函数 (2)Dijkstra函数          (3)Search函数          (4)Menu函数          (5)main函数          2.4 程序编码   把详细设计的结果进一步求精为程序设计语言程序。同时加入一些注解和断言,使程序中逻辑概念清楚;编写过程中参考各种的教材和材料,使程序编写的正确性大有提高,同时也许到许多实践知识,增加了实践经验。 2.5 程序调试与测试    程序编写总是出现各种各样的错误,但是难点不是修改错误,而是找出错误。在大量的源程序中找出错误难度很大,但有了一定的方法,就能节省大量的时间,在这次课程设计中我运用的调试方法主要有2种:     一是借助调试工具。利用Turbo C中提供的程序专门调试工具Debugger程序,可以很容易找出程序中的各种语法错误。但是遇到一些逻辑错误时却又无从着手。这时我就用下面一种方法。     二是在程序中插入打印语句。猜测出大致的错误位置,选则一些主要变量,在关键部位插入打印语句,打印出这个主要变量,看其是否与理论上的一样,在多个位置插入,如果有个位置的值与理论值一样,另一个位置与理论值不一样,则错误就落在这两个位置之间,然后再多测试几个位置缩小范围,直到找出错误。  例如;我在调试main()主函数时,程序能够运行,三个选项都能选择,创建函数能够正常运行,也能正常退出,但在选第一条进入校园导航后,打印出来的列表却是空的,源程序中的初始化数据没有显示出来,我又尝试输入两个结点进行查找,发现没有输出路线,所以我猜测初始化数据没有被正常写入。但不知道为何没有被正常写入,首先怀疑是初始化时附值发生错误,查阅各种资料进行校验,发现没有错误。后来经过综合分析,发现最有可能是n值在search()函数中发生错误,于是我在search()函数中插入打印n 的语句,运行后发现输出的n为0,初始化数据中有11个结点,n应该为11,所以n 在这个地方发生错误,我又在main()主函数中打印出n 的值,n=11,是正确的。所以错误就在search()函数中,也就说是当运行case1,运行到search()函数时,n从11变为0,针对这个错误,我把变量n改为宏定义,因为n 是代表结点个数,不管在哪个函数中它的值都是一样的才对。改完后运行程序,成功! 本设计文件的注释如上,已给出详细的说明,下面仅以文件为单位说明各个函数的作用和特点,在必要的地方给予一定说明。  3.1、guide.h文件 使用条件编译。以下是头文件中语句 /********************************************* *头文件(.h) ********************************************/ #include "stdio.h" #include "conio.h" #include "alloc.h" #define n0 100 #define infi 32767 /*“无穷大*/ int adjmatrix[n0+1][n0+1];     /*邻接矩阵*/ int n=11; struct node             /*表结点*/ { char name[20];       /*下一个表结点与它们之间的距离*/ }place[12]={{"ShiDiGongYuan"},   /*表结点初始化,即写各景点名称*/    {"CangRongGongYu"},    {"YinHuiLou"},    {"TuoHuanGuanChang"},    {"DiBaShiTang"},    {"XiaoYiYuan"},    {"TuShuGuan"},    {"TiYuGuan"},    {"ZhongHuaGuanChang"},    {"ChuangXinLou"},    {"YiFuTuShuGuan"},    {"BoXueLou"}};  void createadj()          /*建立邻接表*/  void dijkstra( int x,int y)     /*dijkstra求最小生树*/  void search()            /*搜索最短路径*/  menu()               /*菜单函数*/          /********************************************* *建立邻接表 ********************************************/ void createadj()  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值