c++ - 迪杰斯特拉计划
问题描述
我在使用之前在不同程序中使用过的功能时遇到了问题,并且在将它们转换为在这个新程序中使用时遇到了困难。Dijkstra.cpp 从标准输入读取有关加权图的信息并打印输入图的描述、从起始顶点和结束顶点的最短路径以及该路径到标准输出的距离。
这是我收到的所有错误(假设它是一个不完整的程序):
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int trace = 0;
//An object of type Edge is a cell in an adjacency list and represents an edge
//of the graph.
struct Edge
{
int from; //The 'from' direction of the edge.
int to; //The 'to' direction of the edge.
double weight; //The weight of the edge from u to v.
Edge* next; //A pointer to the next edge in the linked list.
Edge(int u, int v, double w, Edge* nextEdge)
{
from = u;
to = v;
weight = w;
next = nextEdge;
}
};
//An object of type Vertex represents information about one vertex in a graph.
struct Vertex
{
Edge* edgeList; //A pointer to a linked list of all edges
//from v to another vertex.
double time; //A real number representing the shortest
//distance from the start vertex.
int sender; //Used with the above real number, it begins
//finding the shortest path starting from v to
//the sender.
Vertex()
{
edgeList = NULL;
time = -1;
sender = -1;
}
};
//An object of type graph represents a weighted graph.
struct Graph
{
int numVertices; //The number of verticies in the graph.
int numEdges; //The number of edges in the graph.
Vertex* vertices; //An array for verticies utilizing a Vertex
//structure that gives information about a
//specific vertex.
Graph(int nV)
{
numVertices = nV;
vertices = new Vertex[nV+1];
numEdges = 0;
}
};
//insertEdge inserts an edge into the graph g.
void insertEdge(int u, int v, int w, Graph* g)
{
Edge newEdge;
newEdge.from = u;
newEdge.to = v;
newEdge.weight = w;
if(g->numVertices > g->numEdges)
{
g->[g->numEdges] = newEdge;
g->numEdges++;
}
}
//insertOpposite inserts an edge going the opposite way
//as insertEdge does into graph g.
void insertOpposite(int u, int v, int w, Graph* g)
{
Edge newEdge;
newEdge.from = v;
newEdge.to = u;
newEdge.weight = w;
if(g->numVertices > g->numEdges)
{
g->vertices[g->numEdges] = newEdge;
g->numEdges++;
}
}
//readGraph reads a graph and is also able to insert edges into a graph.
Graph* readGraph()
{
int nV, u,v,w, edges = 0;
scanf("%i", &nV);
Graph* g = new Graph(nV);
while(true)
{
scanf("%i", &u);
if(u == 0)
{
break;
}
scanf("%i", &v);
scanf("%i", &w);
insertEdge(u, v, w, g);
insertOpposite(u, v, w, g);
edges++;
}
g->totalEdges = edges;
return g;
}
//writeGraph prints a formatted chart from graph g
//that includes the amount of vertices and edges along with
//the weight that corresponds to each edge.
void writeGraph(Graph* g)
{
printf("\nThere are %i vertices and %i edges\n", g->numVertices,
g->numEdges);
printf("\n The edges are as follows.");
for(int n = 0; n < g->totalEdges; n++)
{
printf("(%i,", g->vertices[n].vertex1);
printf("%i) ", g->vertices[n].vertex2);
printf("weight %3i\n", g->vertices[n].weight);
}
}
解决方案
我不会详尽地介绍每个错误,但这里是解决这些错误的一般策略。
在处理来自编译器的错误消息时,最好从第一个错误开始,处理它,然后再次尝试编译。通常,一个问题会导致多条错误消息,解决一个问题可以为其余问题提供线索。如果不出意外,一次处理一件事有助于保持事情的可控性。
让我们看一下第一条错误消息:
dijkstra.cpp: In function ‘void insertEdge(int, int, int, Graph*)
dijkstra.cpp:152:10: error: no matching function for call to ‘Edge::Edge()’
Edge newEdge;
^
1. 查看触发错误的行。
有时在那条线上(或者可能是它上面的线)会有一些明显的东西。缺少分号、被遗忘的论点、错字等。
您的编译器已告诉您在哪里查看。错误dijkstra.cpp
在 line number 152
。它还为我们提供了它所在函数的签名:void insertEdge(int, int, int, Graph*)
. 事实上,它甚至可以指出它意识到哪里出了问题:当你的程序试图创建一个Edge
被调用的newEdge
.
2. 解释错误信息。
对于不明显的错误,您可能需要深入了解错误消息的含义。在这种情况下,列出的错误是:no matching function for call to 'Edge::Edge()'
。
这对我来说似乎是不言自明的,但当然,这取决于阅读信息的人的经验水平。如果我不理解错误消息,我会采用一个简单的策略:我在 Google 上搜索它。删除特定于您的程序的名称将很有用,因此在这种情况下,我可能会搜索"error: no matching function for call to"
. 这样做会给面临类似错误的程序员带来许多结果。
在这种特定情况下,编译器说您正在尝试调用该函数Edge::Edge()
,但找不到与之匹配的函数。Edge::Edge()
将是您的Edge
结构的构造函数 - 但您只定义了一个构造函数,并且它需要几个参数,因此编译器不知道如何构造一个Edge
没有任何参数的构造函数。
3.修复错误
对于此特定错误,您可以更改引用的行以使用参数创建一个Edge
。就像是:
Edge newEdge(0, 0, 0.0, nullptr)
但这可能不是你想要的。更有可能的是,您希望将默认构造函数添加到您的Edge
结构中。
struct Edge
{
...
Edge(int u, int v, double w, Edge* nextEdge)
{
from = u;
to = v;
weight = w;
next = nextEdge;
}
Edge() = default; // Creates a default constructor; leaves values uninitialized
};
或者
struct Edge
{
...
Edge(int u, int v, double w, Edge* nextEdge)
{
from = u;
to = v;
weight = w;
next = nextEdge;
}
Edge() : from(0), to(0), weight(0.0), next(nullptr) {} // Initializes members to a set of defaults
};
或者
struct Edge
{
...
Edge(int u = 0, int v = 0, double w = 0.0, Edge* nextEdge = nullptr) // Defines default values so that constructor can be called with 0-4 arguments
{
from = u;
to = v;
weight = w;
next = nextEdge;
}
};
4. 重复
现在你重新编译你的程序。希望错误消息的数量有所减少。无论如何,您查看列表中的第一个错误,然后重复此过程,直到您的程序编译没有错误。
推荐阅读
- elixir - 在伞形应用程序混合文件中使别名动态化
- php - 为什么我不能在我的 laravel 控制器中调用函数?
- r - rstudio 中的图是否保存到索引中?
- postgresql - pgadmin4,得到“无法连接到服务器:SSL 错误:无效填充”错误
- java - 需要将下划线分隔的单词转换为人类可读的形式?
- java - 在 Android 中订阅字符串
- vb.net - 如何从 Spotify 拖放到 Winforms 应用程序
- java-8 - 如何强制 Liferay Dev Studio 使用我指定的 JDK?(JDK8)
- javascript - 如果文本框不为空,则拒绝刷新页面
- ocaml - 我正在尝试测试此流动性智能合约代码,但如果显示错误。流动性类似于 tezos 的智能合约语言 ocaml。