7.16第三周

 这周一直在搞数据结构 遇见了很多问题 复习了c++ 对自己的算法有了一定提升

结果:terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid

    1.  
      #include <iostream>
    2.  
      #include <sstream>
    3.  
      #include <string.h>
    4.  
      #include <vector>
    5.  
      #include<fstream>
    6.  
      #define MaxInt 32767 //表示极大值,即∞
    7.  
      #define MVNum 100 //最大顶点数
    8.  
      using namespace std;
    9.  
      typedef int ArcType; //假设边的权值类型为整型
    10.  
       
    11.  
      int *D=new int[MVNum]; //用于记录最短路的长度
    12.  
      bool *S=new bool[MVNum](); //标记顶点是否进入S集合S={};
    13.  
      int *Path=new int[MVNum]; //用于记录最短路顶点的前驱
    14.  
       
    15.  
      //------------图的顶点结构-----------------
    16.  
      typedef struct{
    17.  
      char name[100];
    18.  
      char info[1000];
    19.  
      }VertexType; //顶点结构
    20.  
       
    21.  
      //------------图的邻接矩阵-----------------
    22.  
      typedef struct{
    23.  
      VertexType vexs[MVNum]; //顶点表
    24.  
      ArcType arcs[MVNum][MVNum]; //邻接矩阵
    25.  
      int vexnum,arcnum; //图的当前点数和边数
    26.  
      }AMGraph;
    27.  
       
    28.  
      int LocateVex(AMGraph G , string vname){
    29.  
      //确定点v在G中的位置
    30.  
      for(int i = 0; i < G.vexnum; ++i)
    31.  
      if(G.vexs[i].name== vname)
    32.  
      return i;
    33.  
      return -1;
    34.  
      }//LocateVex
    35.  
       
    36.  
      //定义字符串分割函数
    37.  
      vector<string> split(const string& str, const string& delim) {
    38.  
      vector<string> res;
    39.  
      if("" == str) return res;
    40.  
      //先将要切割的字符串从string类型转换为char*类型
    41.  
      char * strs = new char[str.length() + 1] ; //不要忘了
    42.  
      strcpy(strs, str.c_str());
    43.  
       
    44.  
      char * d = new char[delim.length() + 1];
    45.  
      strcpy(d, delim.c_str());
    46.  
       
    47.  
      char *p = strtok(strs, d);
    48.  
      while(p) {
    49.  
      string s = p; //分割得到的字符串转换为string类型
    50.  
      res.push_back(s); //存入结果数组
    51.  
      p = strtok(NULL,d);
    52.  
      }
    53.  
       
    54.  
      return res;
    55.  
      }
    56.  
       
    57.  
      void CreateUDN(AMGraph &G,char filename[]){
    58.  
      //采用邻接矩阵表示法,创建无向网G
    59.  
      FILE *in;
    60.  
      char *ch=new char[1000];
    61.  
      char* s;
    62.  
      vector<string> res;
    63.  
      if((in=fopen(filename,"r"))==NULL){
    64.  
      cout<<"无法打开graph文件!"<<endl;
    65.  
      exit(0);
    66.  
      }
    67.  
      //读取总顶点数,总边数
    68.  
      fgets(s,1000,in);
    69.  
      res=split(s, " ");
    70.  
      stringstream ss,kk;
    71.  
      ss<<res[0];
    72.  
      ss>>G.vexnum;
    73.  
      cout<<G.vexnum<<endl;
    74.  
      kk<<res[1];
    75.  
      kk>>G.arcnum;
    76.  
      cout<<G.arcnum<<endl;
    77.  
      //读取顶点信息
    78.  
      for(int i=0;i<G.vexnum;i++){
    79.  
      fgets(s,1000,in);
    80.  
      res=split(s, " ");
    81.  
      strcpy(G.vexs[i].name, res[0].c_str());
    82.  
      strcpy(G.vexs[i].info, res[1].c_str());
    83.  
      }
    84.  
      //读取边的信息
    85.  
      int m,n;
    86.  
      for(int i=0;i<G.arcnum;i++){
    87.  
      stringstream zz;
    88.  
      fgets(s,1000,in);
    89.  
      res=split(s, " ");
    90.  
      m = LocateVex(G, res[0]); n = LocateVex(G, res[1]); //确定两个顶点在G中的位置,即顶点数组的下标
    91.  
      zz<<res[2];
    92.  
      zz>>G.arcs[m][n]; //设置边的权重
    93.  
      G.arcs[n][m] = G.arcs[m][n];
    94.  
      zz.str("");
    95.  
      }
    96.  
      fclose(in);
    97.  
      }//CreateUDN
    98.  
       
    99.  
      void ShortestPath_DIJ(AMGraph G, int v0){
    100.  
      //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
    101.  
      int v , i , w , min;
    102.  
      int n = G.vexnum; //n为G中顶点的个数
    103.  
       
    104.  
      for(v = 0; v < n; ++v){ //n个顶点依次初始化
    105.  
      S[v] = false; //S初始为空集
    106.  
      D[v] = G.arcs[v0][v]; //将v0到各个终点的最短路径长度初始化为弧上的权值
    107.  
      if(D[v] < MaxInt) Path [v] = v0; //如果v0和v之间有弧,则将v的前驱置为v0
    108.  
      else Path [v] = -1; //如果v0和v之间无弧,则将v的前驱置为-1
    109.  
      }//for
    110.  
       
    111.  
      S[v0]=true; //将v0加入S
    112.  
      D[v0]=0; //源点到源点的距离为0
    113.  
       
    114.  
      /*―初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
    115.  
      for(i = 1;i < n; ++i){ //对其余n-1个顶点,依次进行计算
    116.  
      min= MaxInt;
    117.  
      for(w = 0; w < n; ++w)
    118.  
      if(!S[w] && D[w] < min){ //选择一条当前的最短路径,终点为v
    119.  
      v = w;
    120.  
      min = D[w];
    121.  
      }//if
    122.  
      S[v]=true; //将v加入S
    123.  
      for(w = 0;w < n; ++w) //更新从v0出发到集合V?S上所有顶点的最短路径长度
    124.  
      if(!S[w] && (D[v] + G.arcs[v][w] < D[w])){
    125.  
      D[w] = D[v] + G.arcs[v][w]; //更新D[w]
    126.  
      Path [w] = v; //更改w的前驱为v
    127.  
      }//if
    128.  
      }//for
    129.  
      }//ShortestPath_DIJ
    130.  
       
    131.  
      void DisplayPath(AMGraph G, int begin,int temp ){
    132.  
      //显示最短路
    133.  
      //cout<<Path[temp]<<endl;
    134.  
      if(Path[temp] != -1){
    135.  
      DisplayPath(G, begin,Path[temp]);
    136.  
      cout<<G.vexs[Path[temp]].name<<"-->";
    137.  
      }
    138.  
       
    139.  
      }//DisplayPath
    140.  
       
    141.  
      int main()
    142.  
      {
    143.  
      //cout << "************算法6.10 迪杰斯特拉算法**************" << endl << endl;
    144.  
      AMGraph G;
    145.  
      int i , j ,fuwu,jd,start, destination;
    146.  
      char f1[]={"graph.txt"};
    147.  
      CreateUDN(G,f1);
    148.  
      cout <<endl;
    149.  
      cout << "*****无向网G创建完成!*****" << endl;
    150.  
       
    151.  
      for(i = 0 ; i < G.vexnum ; ++i){
    152.  
      for(j = 0; j < G.vexnum; ++j){
    153.  
      if(j != G.vexnum - 1){
    154.  
      if(G.arcs[i][j] != MaxInt)
    155.  
      cout << G.arcs[i][j] << "\t";
    156.  
      else
    157.  
      cout << "∞" << "\t";
    158.  
      }
    159.  
      else{
    160.  
      if(G.arcs[i][j] != MaxInt)
    161.  
      cout << G.arcs[i][j] <<endl;
    162.  
      else
    163.  
      cout << "∞" <<endl;
    164.  
      }
    165.  
      }
    166.  
      }//for
    167.  
       
    168.  
      cout << "************欢迎来到**************" << endl << endl;
    169.  
      cout << " 1.查询景点信息 "<<endl;
    170.  
      cout << " 2.问路查询 "<<endl;
    171.  
      cout << " 3.退出 "<<endl;
    172.  
      cout<<"*****************请选择需要的服务(1-3)****************"<<endl;
    173.  
      cin>>fuwu;
    174.  
      switch(fuwu){
    175.  
      case 1:cout<<"本校景点有:"<<endl;
    176.  
      for(i=0;i<G.vexnum;i++){
    177.  
      cout<<i<<":"<<G.vexs[i].name<<endl;
    178.  
      }
    179.  
      cout<<"请选择需要查询的景点"<<endl;
    180.  
      cin>>jd;
    181.  
      cout<<G.vexs[jd].info<<endl;
    182.  
      case 2:cout<<"本校景点有:"<<endl;
    183.  
      for(i=0;i<G.vexnum;i++){
    184.  
      cout<<i<<":"<<G.vexs[i].name<<endl;
    185.  
      }
    186.  
      cout<<"请输入您的所在地"<<endl;
    187.  
      cin>>start;
    188.  
      cout<<"请输入您的目的地"<<endl;
    189.  
      cin>>destination;
    190.  
      ShortestPath_DIJ(G,start);
    191.  
      cout<<"路径是:";
    192.  
      DisplayPath(G,start,destination);
    193.  
      cout<<G.vexs[destination].name<<endl<<"最短距离是:"<<endl;
    194.  
      cout<<D[destination]<<endl;
    195.  
      case 3: exit(0);
    196.  
      }
    197.  
      return 0;
    198.  
      }//main
    199.  
    200. c++读取文件出现乱码的原因时在保存文件的时候,编码格式默认的比如UTF-8格式不支持汉字编码,因此,在保存txt文本文件时,改变编码格式即可。

      如下,打开记事本,另存为,文件名下方会出现编码的选择,将默认的UTF-8改成ANSI即可,因为ANSI编码支持汉字编码,所以不会出现乱码。

       


      ————————————————
      版权声明:本文为CSDN博主「云兮杜康」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://blog.csdn.net/weixin_53717695/article/details/123590267

       
posted @ 2022-07-16 20:42  stdxxd  阅读(31)  评论(0)    收藏  举报