首页 > 解决方案 > 迪杰斯特拉计划

问题描述

我在使用之前在不同程序中使用过的功能时遇到了问题,并且在将它们转换为在这个新程序中使用时遇到了困难。Dijkstra.cpp 从标准输入读取有关加权图的信息并打印输入图的描述、从起始顶点和结束顶点的最短路径以及该路径到标准输出的距离。

这是我收到的所有错误(假设它是一个不完整的程序):

附上1 附上2

#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);
    }
}

标签: c++dijkstra

解决方案


我不会详尽地介绍每个错误,但这里是解决这些错误的一般策略。

在处理来自编译器的错误消息时,最好从第一个错误开始,处理它,然后再次尝试编译。通常,一个问题会导致多条错误消息,解决一个问题可以为其余问题提供线索。如果不出意外,一次处理一件事有助于保持事情的可控性。

让我们看一下第一条错误消息:

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. 重复

现在你重新编译你的程序。希望错误消息的数量有所减少。无论如何,您查看列表中的第一个错误,然后重复此过程,直到您的程序编译没有错误。


推荐阅读