Esquema de aplicación (mapa del campus para resolver el camino más corto)

En primer lugar, los requisitos experimentales:

Diseño del plan de campus de la Universidad de Sichuan luz de la Industria Química, no menos de ocho atracciones contenía. En la FIG atracciones escolares Vertex, atracciones de nombre de la tienda, la información atracciones; Edge dicha información longitud del recorrido ruta, el almacenamiento. La información solicitada se almacena en un archivo de graph.txt, el sistema de procesamiento de datos para realizar la lectura y escritura de este archivo, respectivamente.

1. Graph.txt lee desde el archivo de los datos correspondientes, para crear un gráfico usando la representación matricial de adyacencia en la figura (algoritmo 6.1);.
2. Atracciones Información de consulta: Proporciona el campus introducción ninguna información sobre las atracciones para los huéspedes que visitan;
3. Pedir a la consulta: cualquier campus ofrece un camino más corto (Algoritmo 6.10) entre las dos atracciones para los huéspedes que visitan.

(Se debe reflejarse cuando el archivo después de la operación, cambie la información adecuada, realizar consultas y solicitar información sobre los lugares de consulta de nuevo) seleccionado como el contenido

  1. Modificar un atracciones existentes de información relevante;
  2. Añadir un nuevo atractivo e información relacionada;
  3. Añadir un nuevo camino;
  4. Eliminar una atracción e información relacionada;
  5. Para eliminar una ruta.
    Para lograr indicador:
  6. carretera campus es el tráfico bidireccional, se puede establecer un plan de campus se pondera grafo no dirigido indica la red sin matriz de adyacencia.

struct {typedef
char nombre [100];
info char [10000];
} VertexType; // vértice estructura
typedef struct {
vexs VertexType [10];
ARCS int [100] [100]; // adyacencia matriz
int vexnum, arcnum; / / número de vértices, el número de borde
} mgraph; // estructura de la Fig.
2. la Fig información vértice y el borde de almacenamiento de información de archivo de datos graph.txt, los datos de formato de archivo puede ser proporcionado en la forma como sigue:
la figura cuente el número de la parte superior de la
puntos de interés nombre de
inicio finalizacion punto de la longitud del camino

Como se puede almacenar en un archivo graph.txt los siguientes datos:
815
restaurantes de alta cocina Pinzheng, buena comida
es Misono una cantina, sabroso
......
Pinzheng 100 East Gate restaurante
puerta sureste Pinzheng 400 restaurantes
......
Aquí Insertar imagen Descripción

En segundo lugar, el código del experimento

#include<stdio.h>
#include<conio.h>
#include<iostream>
#include<assert.h>
#include<string.h>
#include<fstream>
#include <vector>
#define INF 123456
#define MaxSize 32476
using namespace std;
typedef struct{ 
	char name[100];
	char info[10000];
}VertexType;      //顶点结构[name+info] 
typedef struct{ 
	VertexType vexs[10];
	int arcs[100][100];   //邻接矩阵
	int vexnum,arcnum;    //顶点、边的个数 
}MGraph;
//确定边的位置 
int locatevex(MGraph &G,char v[],int vexnum){
	for(int i=0;i<vexnum;i++){
		if(v==G.vexs[i].name){
			return i;
		}
	}
}
//输出所有景点的名称 
void show_vex(MGraph &G){
	for(int i=0;i<G.vexnum;i++){
		cout<<i+1<<"."<<G.vexs[i].name<<endl;
	}
}
//输出所有景点的详细信息
void show_info(MGraph &G,int index){ 
	cout<<"对应景点信息为:"<<index<<"."<<G.vexs[index-1].info<<endl;
}

//获取编号 
int getVerNum(MGraph &G,char* name){
	int i;
	for(i=0;i<G.vexnum;i++){
		if(strcmp(name,G.vexs[i].name)==0){
			return i;
		}
	}
	if(i>G.vexnum){
		return -1;
	}
		
} 
// 最短路径Dijkstra算法
/*
v: 求编号为v的顶点到其它点的最短路径。
path: 路径存放在path数组中。 path[i] 存放 到i的前驱结点编号, path[3] = 1 表示: 顶点3是从1过来的
*/
void Dijkstra(MGraph &G,int v,int path[],int dist[]){
    int s[MaxSize];// 已找到最短路径的点的集合
    bool Final[MaxSize];//Final[w]=1表示求得顶点V0至Vw的最短路径
    // 初始化dist\path: path[i] 存放 到i的前驱结点编号, -1表示没有
    for (int i = 0; i < G.vexnum; i++){
        Final[i] = false;
        dist[i] = G.arcs[v][i];
        if (dist[i] != INF){
            path[i] = v;
        }
        else{
            path[i]=-1;
        }
    }
    s[0] = v; // 初始化s
    Final[v] = true;
    int num = 1;
    while (num < G.vexnum){
        // 在dist中查找最小值元素
        int k = 0,min= INF;
        for (int i = 0; i < G.vexnum; i++)
        {
            if (i == v)continue;
            if (!Final[i] && dist[i] < min)
            {
                k = i;
                min = dist[i];
            }                
        }
        s[num++] = k;// 将新生成的结点加入集合s
        Final[k] = true;
        // 修改dist和path数组
        for (int i = 0; i < G.vexnum; i++){
            if (!Final[i] && dist[i] > dist[k] + G.arcs[k][i])
            {
                dist[i] = dist[k] + G.arcs[k][i];
                path[i] = k;
            }
        }
    }
}
/* char*tostr  字符串转化str类型
输入:char * 字符串地址   
无输出
返回值: str类型的字符串
*/
string charToStr(char * contentChar)
{
	string str;
	for (int i=0;contentChar[i]!='\0';i++)
	{
		str+=contentChar[i];
	}
	return str;
}

/* 修改文件某行内容
 输入:文件名 fileName   行号   lineNum ,修改的内容 content
 输出:文件名 fileName
 无返回值
 tip:1,lineNum从第一行开始 2.content需要加上换行符
*/
void modifyContentInFile(char *fileName,int lineNum,char *content)
{
	ifstream in;
	char line[1024]={'\0'};
	in.open(fileName);
	int i=0;
	string tempStr;
	while(in.getline(line,sizeof(line)))
	{
		i++;
		if(lineNum!=i)
		{
			tempStr+=charToStr(line);
		}
		else
		{
	       tempStr+=charToStr(content);
		}
		tempStr+='\n';
	}
	in.close();
	ofstream out;
	out.open(fileName);
	out.flush();
	out<<tempStr;
	out.close();
}
void CreatGraph(MGraph &G){
	ifstream in("Graph.txt");
	in>>G.vexnum>>G.arcnum;
	for(int i=0;i<G.vexnum;i++){
		in>>G.vexs[i].name;
		in>>G.vexs[i].info;
	} 
	//输出 
	//初始化边的权值
	for(int i=0;i<G.vexnum;i++){
		for(int j=0;j<G.vexnum;j++){
			G.arcs[i][j]=INF;
		}
	}
	//输入边的信息
	for(int i=0;i<G.arcnum;i++){
		int m,n,cost;
		char tname1[MaxSize],tname2[MaxSize];
		
		in>>tname1>>tname2>>cost;
		m=getVerNum(G,tname1);
		n=getVerNum(G,tname2);
		//如果m n为-1,表示输入有错
		assert(m!=-1&&n!=-1); 
		G.arcs[m][n]=cost;
		G.arcs[n][m]=cost;
	}	
}

/*删除文本文件的空行*/
void deletenull(string file){
	vector<string> file_data;
    string file_name = file;
    fstream file_in(file_name.c_str(), fstream::in);
    string temp = "";
    while( getline(file_in, temp) ) {
        if( temp != ""){
            file_data.push_back(temp);
        }
    }
    file_in.close();
    //remove(file_name.c_str());
    fstream file_out(file_name.c_str(), fstream::out);
    for(vector<string>::iterator i = file_data.begin(); i != file_data.end(); i++){
        file_out<<*i<<endl;
    }
}
int main(){
	while(1){
		cout<<"***************欢迎来到四川轻化工大学********"<<endl;
		cout<<"1.	查询景点信息"<<endl;
		cout<<"2.	问路查询"<<endl;
		cout<<"3.	修改一个已有景点的相关信息;"<<endl;
		cout<<"4.      增加一个新景点及其相关信息"<<endl;
		cout<<"5.      增加一条新的路径"<<endl;
		cout<<"6.      删除一个景点及其相关信息"<<endl;
		cout<<"7.      删除一条路径"<<endl;
		cout<<"#.	退出"<<endl;
		cout<<"***************轻化工校园导游系统**********"<<endl;
		MGraph G;     
		CreatGraph(G);   //首先创建图 
		
		char ch;
		cout<<"请输入:";cin>>ch;
		if(ch=='#'){
			break;
		}else if(ch=='1'){
			cout<<"本校景点有:"<<endl;
			show_vex(G);
			cout<<"-------------"<<endl;
			
			cout<<"请选择您要查询的景点:"<<"(1-"<<G.vexnum<<")"<<"[注:输入0就退出该功能]"<<endl;
			int index;
			while(1){
				cin>>index;
				if(index==0) break;
				if(index>=1&&index<=G.vexnum){
					show_info(G,index);
				} else {
					cout<<"Search failed!"<<endl;
				}
			}
		} else if(ch=='2'){
			cout<<"你选择了问路查询!"<<endl<<"下面显示景点列表:"<<endl;
			show_vex(G);
			cout<<"-------------"<<endl;
			int from,end;
			
			cout<<"请输入你现在的位置:"<<endl;
			while(1){
				cin>>from;
				if(from<=0||from>G.vexnum){
					cout<<"Input failed!Please input the start again:"<<endl;
				} else {
					break;
				}
			} 
			cout<<"请输入你的目的地:"<<endl;
			while(1){
				cin>>end;
				if(end<=0||end>G.vexnum){
					cout<<"Input failed!Please input the end again:"<<endl;
				} else {
					break;
				}
			}
			
			int path[MaxSize];
			int dist[MaxSize];      //v到j的路径长度 
			Dijkstra(G,from-1,path,dist);
			cout<<G.vexs[from-1].name<<"到"<<G.vexs[end-1].name<<"的路径是:"<<endl;
			
			int temp=end-1;         //终点-1作为数组下标 
			int temp1,temp2;        
			int flag[MaxSize],m=0;  
			while(temp!= -1 ){       
				flag[m++]=temp;     //flag[]用来 
				temp1=temp;   
				temp2=path[temp1]; //path[]存放前驱顶点编号。path[temp1]=-1表示没有前驱了。 
				temp=temp2;
			}
			
			for(int i=m-1;i>=0;i--){
				cout<<G.vexs[ flag[i] ].name;
				if(i!=0){
					cout<<"->";
				}
			}
			cout<<endl<<endl;
			cout<<"最短距离是:"<<endl<< dist[end-1] <<"米"<<endl;    //dist[]数组用来存放出发节点v0到每个节点的最短路径; dist[end-1]表示v0到终点的最短路径 
			cout<<"---------------------------------"<<endl;
		} else if(ch=='3'){
			char file[10]="graph.txt";
			cout<<"输入需要修改信息的原景点:"<<endl;
			int i;cin>>i;
			cout<<"将原景点信息改为:---->"<<endl;
			char content[1000]={""},s[100];
			cin>>s;
			strcat(content,G.vexs[i-1].name);      strcat(content," ");     strcat(content,s);
			//cout<<content<<endl;
			modifyContentInFile(file,1+i,content);cout<<"修改景点信息成功!"<<endl;
		} else if(ch=='4'){
			 //增加一个新景点及其相关信息
			cout<<"你选择了增加一个新景点及其相关信息功能!"<<endl;
			cout<<"请输入新景点的name和info:"<<endl;
			char newvexname[MaxSize];char newvexinfo[MaxSize];
			cin>>newvexname;cin>>newvexinfo;
			strcat(newvexname," ");strcat(newvexname,newvexinfo);
			
			char s[MaxSize];
			strcpy(s,G.vexs[G.vexnum-1].name);
			strcat(s," ");  
			strcat(s,G.vexs[G.vexnum-1].info);
			strcat(s,"\n");strcat(s,newvexname);
			cout<<s<<endl;
			//插入到景点末尾;而且将第一行的vexnum+1; 
			char file[10]="graph.txt";
			modifyContentInFile(file,1+G.vexnum,s); 
			char str1[MaxSize];char str2[MaxSize];
			itoa(G.vexnum+1, str1, 10);             //第三个参数表示多少进制 
			itoa(G.arcnum,str2,10);
			strcat(str1," ");strcat(str1,str2);
			modifyContentInFile(file,1,str1);     	//修改第一行 
		} else if(ch=='5'){
			//增加一条新的路径;
			cout<<"你选择了增加一条新的路径!"<<endl<<"请依次输入新路径的起点和终点和路径长度:"<<endl;
			char s1[MaxSize];char s2[MaxSize];char s3[MaxSize];
			cin>>s1>>s2>>s3;
			strcat(s1," ");strcat(s1,s2);strcat(s1," ");strcat(s1,s3); 
			//在文件末尾写入 
			ofstream write;           
		    ifstream read;
		    write.open("graph.txt", ios::app);      //用ios::app不会覆盖文件内容
		    write << s1 << endl;
		    write.close();
		    read.close();
		    //下面把8  15改成8  16,需要将arcnum++,然后第一行转化成字符串,再写入
			char str1[MaxSize];char str2[MaxSize];
			itoa(G.vexnum, str1, 10);    //第三个参数表示多少进制 
			itoa(G.arcnum+1,str2,10);
			strcat(str1," ");strcat(str1,str2);
		    //修改第一行 
		    char file[10]="graph.txt";
			modifyContentInFile(file,1,str1); 
		} else if(ch=='6'){
			//删除一个景点及其相关信息;
			cout<<"你选择了删除一个景点及其相关信息!" <<endl<<"请输入你要删除的景点编号:"<<endl;
			int i;
			cin>>i;
			char file[10]="graph.txt";
			modifyContentInFile(file,1+i,"");     
			
			char str1[MaxSize];char str2[MaxSize];//修改第一行 
			itoa(G.vexnum-1, str1, 10);
			itoa(G.arcnum,str2,10);
			strcat(str1," ");strcat(str1,str2);
			modifyContentInFile(file,1,str1); 
			
			string file1="graph.txt";
			deletenull(file1);
		} else if(ch=='7'){
			//删除一条路径
			cout<<"你选择了删除一条路径功能!"<<endl;
			ifstream in("graph.txt");
			string str;
			string temp;
			for(int i=0;i<1+G.vexnum;i++){
				getline(in,temp);
			}
			cout<<"以下展示出所有路径:"<<endl;
			for(int i=0;i<G.arcnum;i++){
				getline(in,str);
				cout<<i+1<<"."<<str<<endl;
			}

			cout<<"请输入删除的路径(1-"<<G.arcnum<<"):"<<endl; 
			int index; cin>>index;
			char file[10]="graph.txt";
			modifyContentInFile(file,1+G.vexnum+index,"");  //删除路径 
			char str1[MaxSize];char str2[MaxSize];
			itoa(G.vexnum, str1, 10);   
			itoa(G.arcnum-1,str2,10);
			strcat(str1," ");strcat(str1,str2);
			modifyContentInFile(file,1,str1);   //修改第一行 
			string file1="graph.txt";
			deletenull(file1);

		} else {
			//如果输入不为1-7和#的话
			cout<<"------------------"<<endl<<"Input failed!Please input again!"<<endl<<"------------------"<<endl; 
		}
	}
	return 0;
}

En tercer lugar, compilar y ejecutar tiros:

Aquí Insertar imagen Descripción

En cuarto lugar, adjuntar contenido (para probar) archivo de datos "graph.txt":

Aquí Insertar imagen Descripción

V. Nota:

En el "mapa" de datos de añadir, borrar, cambiar, procesamiento experimental requiere el archivo.
Además del método básico, además de lo cual hay varias funciones o algoritmos puede pensar profundamente estudiar:

1. Las líneas en blanco de borrado en el archivo:

void deletenull(string file){
	vector<string> file_data;
    string file_name = "1.txt";
    fstream file_in(file_name.c_str(), fstream::in);
    string temp = "";
    while(getline(file_in, temp)){
        if( temp != ""){
            file_data.push_back(temp);
        }
    }
    file_in.close();
    //remove(file_name.c_str());
    fstream file_out(file_name.c_str(), fstream::out);
    for(vector<string>::iterator i = file_data.begin(); i != file_data.end(); i++){
        file_out<<*i<<endl;
    }
}

2. Modificar el contenido de la fila archivo especificado

/* 修改文件某行内容
 输入:文件名 fileName   行号   lineNum ,修改的内容 content
 输出:文件名 fileName
 无返回值
 tip:1,lineNum从第一行开始 2.content需要加上换行符
*/
void modifyContentInFile(char *fileName,int lineNum,char *content)
{
	ifstream in;
	char line[1024]={'\0'};
	in.open(fileName);
	int i=0;
	string tempStr;
	while(in.getline(line,sizeof(line)))
	{
		i++;
		if(lineNum!=i)
		{
			tempStr+=charToStr(line);
		}
		else
		{
	       tempStr+=charToStr(content);
		}
		tempStr+='\n';
	}
	in.close();
	ofstream out;
	out.open(fileName);
	out.flush();
	out<<tempStr;
	out.close();
}

Cadena tipo char * en una cadena de tipo string

/* char*tostr  字符串转化str类型
输入:char * 字符串地址   
无输出
返回值: str类型的字符串
*/
string charToStr(char * contentChar)
{
	string str;
	for (int i=0;contentChar[i]!='\0';i++)
	{
		str+=contentChar[i];
	}
	return str;
}

3. El algoritmo de la ruta más corta (en este caso, el algoritmo de Dijkstra, el algoritmo de Floyd puede adicionalmente referencia):

// 最短路径Dijkstra算法
/*
v: 求编号为v的顶点到其它点的最短路径。
path: 路径存放在path数组中。 path[i] 存放 到i的前驱结点编号, path[3] = 1 表示: 顶点3是从1过来的
*/
void Dijkstra(MGraph &G,int v,int path[],int dist[]){
    int s[MaxSize];// 已找到最短路径的点的集合
    bool Final[MaxSize];//Final[w]=1表示求得顶点V0至Vw的最短路径
    // 初始化dist\path: path[i] 存放 到i的前驱结点编号, -1表示没有
    for (int i = 0; i < G.vexnum; i++){
        Final[i] = false;
        dist[i] = G.arcs[v][i];
        if (dist[i] != INF){
            path[i] = v;
        }
        else{
            path[i]=-1;
        }
    }
    s[0] = v; // 初始化s
    Final[v] = true;
    int num = 1;
    while (num < G.vexnum){
        // 在dist中查找最小值元素
        int k = 0,min= INF;
        for (int i = 0; i < G.vexnum; i++)
        {
            if (i == v)continue;
            if (!Final[i] && dist[i] < min)
            {
                k = i;
                min = dist[i];
            }                
        }
        s[num++] = k;// 将新生成的结点加入集合s
        Final[k] = true;
        // 修改dist和path数组
        for (int i = 0; i < G.vexnum; i++){
            if (!Final[i] && dist[i] > dist[k] + G.arcs[k][i])
            {
                dist[i] = dist[k] + G.arcs[k][i];
                path[i] = k;
            }
        }
    }
}

Si tiene problemas, puede añadir mi QQ: 1030567595, tanto como sea posible para ayudar a resolver.

Publicado 69 artículos originales · ganado elogios 22 · vistas 5989

Supongo que te gusta

Origin blog.csdn.net/Kevin__Coder/article/details/90723964
Recomendado
Clasificación