C++ 贝尔曼福特解析源和;目标为字符而不是整数

C++ 贝尔曼福特解析源和;目标为字符而不是整数,c++,arrays,data-structures,character,bellman-ford,C++,Arrays,Data Structures,Character,Bellman Ford,我正在从事一项数据结构作业,该作业要求我从一个包含源、目标和权重(例如t、x、5)的文件中读取数据,并且我使用了诸如Geeksforgeks之类的在线资源,在那里我修改了代码以使其正常工作。虽然我现在做的是一种破解/解决方法,读取字符并将其转换为整数,这基本上违背了目的。 我希望按原样分析字符,而不是将其转换为整数。 参考: 所以基本上我所做的是,我把{s,t,x,y,z}当作{0,1,2,3,4}来处理,这基本上是有效的 if(a[0]=='s') { graph->edge[inde

我正在从事一项数据结构作业,该作业要求我从一个包含源、目标和权重(例如t、x、5)的文件中读取数据,并且我使用了诸如Geeksforgeks之类的在线资源,在那里我修改了代码以使其正常工作。虽然我现在做的是一种破解/解决方法,读取字符并将其转换为整数,这基本上违背了目的。 我希望按原样分析字符,而不是将其转换为整数。 参考: 所以基本上我所做的是,我把{s,t,x,y,z}当作{0,1,2,3,4}来处理,这基本上是有效的

if(a[0]=='s')
{
 graph->edge[index].src = 0;
}
等等

正在读取的文件

t,x,5
t,y,8
t,z,-4
x,t,-2
y,x,-3
y,z,9
z,x,7
z,s,2
s,t,6
s,y,7 
这是它的工作代码

#include<bits/stdc++.h>
#include<fstream>
#include<string>

using namespace std;

struct Edge { 
  int s, d, w; 
}; 
struct Graph { 
  int V, E;  
  struct Edge* edge; 
}; 
struct Graph* createGraph(int V, int E) 
{ 
  struct Graph* graph = new Graph; 
  graph->V = V; 
  graph->E = E; 
  graph->edge = new Edge[E]; 
  return graph; 
} 

void initialize_single_source(int distance[],int V, int s)
{
  for (int i = 0; i < V; i++) 
  {
    distance[i] = INT_MAX; 
  }
  distance[s] = 0; 
}

void relax(int distance[], int u, int v, int w)
{
     if (distance[v] > distance[u] + w && distance[u] != INT_MAX)
     {
        distance[v] = distance[u] + w; 
     }
}

void display(int distance[], int n) 
{ 
    char vertex[] = {'s','t','x','y','z'};
    cout << "Vertex   Distance from Source\n";
    for (int i = 0; i < n; ++i)
    cout << vertex[i] << "\t\t" << distance[i] << "\n"; 
} 

bool bellman_ford(struct Graph* graph, int s) 
{ 
  int V = graph->V; 
  int E = graph->E; 
  int distance[V]; 

  initialize_single_source(distance,V,s);

  for (int i = 1; i <= V - 1; i++)
  { 
    for (int j = 0; j < E; j++) 
    { 
      int u = graph->edge[j].s; 
      int v = graph->edge[j].d; 
      int w = graph->edge[j].w; 
      relax(distance,u,v,w);
    } 
  } 

  for (int i = 0; i < E; i++) { 
    int u = graph->edge[i].s; 
    int v = graph->edge[i].d; 
    int w = graph->edge[i].w; 
    if (distance[v] > distance[u] + w && distance[u] != INT_MAX) 
      return false; 
  } 

  display(distance, V); 

  return true; 
} 

int main() 
{ 
  int V = 5; 
  int E = 10; 
  struct Graph* graph = createGraph(V, E); 
  int index = 0;
  string a;
  ifstream infile("adjlist.txt");
  while(getline(infile,a))
{   
  if(a[0]=='s')
    {
    graph->edge[index].s = 0;
    }
    else if(a[0]=='t')
    {
    graph->edge[index].s = 1;
    }
    else if(a[0]=='x')
    {
    graph->edge[index].s = 2;
    }
    else if(a[0]=='y')
    {
    graph->edge[index].s = 3;
    }
    else if(a[0]=='z')
    {
    graph->edge[index].s = 4;
    }

    if(a[2]=='s')
    {
    graph->edge[index].d = 0;
    }
    else if(a[2]=='t')
    {
    graph->edge[index].d = 1;
    }
    else if(a[2]=='x')
    {
    graph->edge[index].d = 2;
    }
    else if(a[2]=='y')
    {
    graph->edge[index].d = 3;
    }
    else if(a[2]=='z')
    {
    graph->edge[index].d = 4;
    }

    if(a[4]!='-')
    {
    graph->edge[index].w = a[4]-'0';
    }
    else
    {
    graph->edge[index].w = -(a[5]-'0');
    }
    index++;
}
  bellman_ford(graph, 0); 

  return 0; 
} 

一种可能的解决方案是重写
Edge
,如下所示

struct Edge { 
  char s, d;
  int w;
}; 
并使用
std::map
表示邻接列表。请注意,这将要求您以某种方式跟踪权重,并相应地更改代码的其余部分


另一方面,@user4581301提到,包括
bits/stdc++
是不好的做法。有关更多详细信息,请参见。

在实现图形算法时,将顶点标签从字符串或其他稀疏类型转换为密集整数实际上非常常见,并且非常有用

我们这样做是为了使用数组或向量来存储与顶点对应的其他内容,而不是像地图这样更复杂的结构

不过,标签映射应该动态构建,这取决于您实际拥有的标签,而不是硬编码。您可以使用
std::map
这样做:

int getVertexNumber(char c) {
    auto it = label_map.find(c);
    int num;
    if (it != label_map.end()) {
        // already had a mapping for this label
        num = it->second;
    } else {
        // new label, starting at 0
        num = (int)label_map.size();
        label_map[c] = num;
    }
    return num;
} 

嘿,在写问题之前我试过这样做,虽然它不能解决我的问题;intv=图->边[j].d;是否正在访问?我似乎无法修复如此简单的问题,这一直困扰着我。请编辑您的问题,将代码包括在内,然后,请参见
int getVertexNumber(char c) {
    auto it = label_map.find(c);
    int num;
    if (it != label_map.end()) {
        // already had a mapping for this label
        num = it->second;
    } else {
        // new label, starting at 0
        num = (int)label_map.size();
        label_map[c] = num;
    }
    return num;
}