解决此C ++代码

时间:2017-03-05 22:45:38

标签: c++ graph compiler-errors dijkstra

我编写了代码(下面的参考)来计算从开始顶点结束顶点的移动次数。

免除了代码逻辑的验证,我对这段代码的编译错误感到有些不知所措。 我想我能理解错误发生的原因,但我不确定解决错误的最佳方法。所以我真的可以在那里使用一些帮助。

下面列出了给我编译错误的行,我认为他们为什么会这样做的原因,以及我到目前为止收集到的内容。

第1名

map<Vertex,int> distanceMap;                // distance is the minimum distance required to reach this current visited vertex.
unordered_map<Vertex,Vertex> pathMap;       // pathMap is to trace the path until current visited Vertex. 
unordered_set<Vertex> Q;      

我得到的错误是

no matching function for call to ‘std::unordered_map, std::pair
>::unordered_map()
no matching function for call to ‘std::unordered_set >::unordered_set()’

我已经宣布了 Vertex 类型 像这样

typedef pair<int,int> Vertex; 

那么这里的错误是什么?

第2名

 for(int i = 0; i < rows; ++i)
{
    for(int j = 0; j < cols; ++j)
    {
          Q.insert(make_pair(i,j)); 
    }
}

将该对插入unordered_set时会发生错误。

no matching function for call to ‘std::unordered_set >::insert(std::pair)’

3号

for ( auto it = Q.begin(); it != Q.end(); ++it )
{
    distanceMap[it++] = INT_MAX;
}

错误:

‘class std::unordered_set >’ has no member named ‘begin’
!‘class std::unordered_set >’ has no member named ‘end’

如果自动不适用,如何为此正确声明迭代器?

第4名

Q.erase(Q.find(currVertex));

错误:

‘class std::unordered_set >’ has no member named ‘erase’
!‘class std::unordered_set >’ has no member named ‘find’

5号

 distanceMap[*it] = updateDist;
 pathMap[*it] = currVertex;

错误:

no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘std::pair’)

我知道这里需要某种运算符重载? 我该如何实现?

6号

while(pmap[curr])
// COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
{
    moves+=1;
    curr = pmap[curr];
// COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
}

为此,我还不确定当我已经声明 pmap 类型为unordered_map<Vertex,Vertex> pmap时错误存在的原因 和typedef pair<int,int> Vertex;

完整的参考代码

// ------ UTIL ------- 
/* all required structures for Graph */
typedef pair<int,int> Vertex; 

/* all criteria required to get a vertex */
typedef pair<Vertex, int> MyPairType;


struct CompareSecond
{
    bool operator()(const MyPairType& left, const MyPairType& right) const
    {
        return left.second < right.second;
    }
};

Vertex get_min_distance_vertex(map<Vertex,int> distMap)
{
    pair<Vertex, int> min  = *min_element(distMap.begin(), distMap.end(), CompareSecond());
    return min.first;  // compare (int) distances to get min dist, return vertex.
}

/* count moves */
int countMoves(Vertex target, unordered_map<Vertex,Vertex> pmap)
{
    int moves = 0;
    Vertex curr = target;
    while(pmap[curr])
    // COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
    {
        moves+=1;
        curr = pmap[curr];
    // COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
    }

    return moves;
}

/* get neighbours */
vector<Vertex> get_neighbours(Vertex curr, int rows, int cols)
{
    vector<Vertex> n;
    if (curr.first <rows && curr.second <cols)
    {
        if( curr.first+1 < cols && curr.second+2 < rows)
            n.push_back(make_pair(curr.first+1,curr.second+2));
        if( curr.first+2 < cols && curr.second+1 < rows)
            n.push_back(make_pair(curr.first+2,curr.second+1));
        if( curr.first+2 < cols && curr.second-1 < rows)
            n.push_back(make_pair(curr.first+2,curr.second-1));
        if( curr.first+1 < cols && curr.second-2 < rows)
            n.push_back(make_pair(curr.first+1,curr.second-2));

        if( curr.first-1 < cols && curr.second+2 < rows)
            n.push_back(make_pair(curr.first-1,curr.second+2));
        if( curr.first-2 < cols && curr.second+1 < rows)
            n.push_back(make_pair(curr.first-2,curr.second+1));
        if( curr.first-2 < cols && curr.second-1 < rows)
            n.push_back(make_pair(curr.first-2,curr.second-1));
        if( curr.first-1 < cols && curr.second-2 < rows)
            n.push_back(make_pair(curr.first-1,curr.second-2));
    }
    return n;

}
/* get distance */
int distance_between_vertices(Vertex source, Vertex target)
{
    float x =  (source.first - target.first)*(source.first - target.first);
    float y =  (source.second - target.second)*(source.second - target.second);
    return (int) sqrt(x+y);
}

// --------------- 
int minimumMoves(int rows, int cols, int startx, int starty, int endx, int endy) {


    Vertex source = make_pair(startx,starty);
    Vertex target = make_pair(endx,endy);

    map<Vertex,int> distanceMap;                // distance is the minimum distance required to reach this current visited vertex.
    unordered_map<Vertex,Vertex> pathMap;       // pathMap is to trace the path until current visited Vertex. 
    unordered_set<Vertex> Q;                    // Q is a set of vertices in chessboard graph.

    // initialize Graph ===> O(N^2) assuming rows = cols = n in a chessboard.
    for(int i = 0; i < rows; ++i)
    {
        for(int j = 0; j < cols; ++j)
        {
              Q.insert(make_pair(i,j)); 
        }
    }

    // Iterate over set, and then assign distanceMap and pathMap values.
    auto it = Q.begin();
    for ( auto it = Q.begin(); it != Q.end(); ++it )
    {
        distanceMap[it++] = INT_MAX;
    }

    // Make distanceMap[source] = 0;
    distanceMap[source] = 0;

    // Dijkstra's.
    // Ref 1 : finding minimum in map -- http://stackoverflow.com/questions/2659248/finding-minimum-value-in-a-map 
    while(!Q.empty())
    {
        Vertex currVertex = get_min_distance_vertex(distanceMap);
        if(currVertex.first==target.first && currVertex.second==target.second){
            return countMoves(currVertex, pathMap);
        }

        Q.erase(Q.find(currVertex));
        vector<Vertex>neighbours = get_neighbours(currVertex,rows,cols);
        if(neighbours.empty())
            break;

        for(auto it = neighbours.begin(); it!= neighbours.end();it++)
        {
            int updateDist = distanceMap[currVertex] + distance_between_vertices(currVertex,*it);
            if (updateDist < distanceMap[*it])
            {
                distanceMap[*it] = updateDist;
                pathMap[*it] = currVertex;
            }
        }
    }


    // return all valid distances here.
    return -1; //no possible move.
}

1 个答案:

答案 0 :(得分:1)

在清理代码并修复明显的语法错误,添加包含等等之后,这里有一个副本:

#include <utility>
#include <map>
#include <vector>
#include <unordered_map>
#include <unordered_set>


// ------ UTIL -------
/* all required structures for Graph */
typedef std::pair<int,int> Vertex;

/* all criteria required to get a vertex */
typedef std::pair<Vertex, int> MyPairType;


struct CompareSecond
{
    bool operator()(const MyPairType& left, const MyPairType& right) const
    {
        return left.second < right.second;
    }
};

Vertex get_min_distance_vertex(std::map<Vertex,int>distMap){
    std::pair<Vertex, int> min  = *min_element(distMap.begin(), distMap.end(), CompareSecond());
    return min.first;  // compare (int) distances to get min dist, return vertex.
}

/* count moves */

int countMoves(Vertex target, std::unordered_map<Vertex,Vertex> pmap)
{
    int moves = 0;
    Vertex curr = target;
    while(pmap[curr])
        // COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
    {
        moves+=1;
        curr = pmap[curr];
        // COMPILE ERROR : no match for ‘operator[]’ (operand types are ‘std::unordered_map, std::pair >’ and ‘Vertex {aka std::pair}’)
    }

    return moves;
}

/* get neighbours */
std::vector<Vertex> get_neighbours(Vertex curr, int rows, int cols)
{
    std::vector<Vertex> n;
    if (curr.first <rows && curr.second <cols)
    {
        if( curr.first+1 < cols && curr.second+2 < rows)
            n.push_back(std::make_pair(curr.first+1,curr.second+2));
        if( curr.first+2 < cols && curr.second+1 < rows)
            n.push_back(std::make_pair(curr.first+2,curr.second+1));
        if( curr.first+2 < cols && curr.second-1 < rows)
            n.push_back(std::make_pair(curr.first+2,curr.second-1));
        if( curr.first+1 < cols && curr.second-2 < rows)
            n.push_back(std::make_pair(curr.first+1,curr.second-2));

        if( curr.first-1 < cols && curr.second+2 < rows)
            n.push_back(std::make_pair(curr.first-1,curr.second+2));
        if( curr.first-2 < cols && curr.second+1 < rows)
            n.push_back(std::make_pair(curr.first-2,curr.second+1));
        if( curr.first-2 < cols && curr.second-1 < rows)
            n.push_back(std::make_pair(curr.first-2,curr.second-1));
        if( curr.first-1 < cols && curr.second-2 < rows)
            n.push_back(std::make_pair(curr.first-1,curr.second-2));
    }
    return n;

}
/* get distance */
int distance_between_vertices(Vertex source, Vertex target)
{
    float x =  (source.first - target.first)*(source.first - target.first);
    float y =  (source.second - target.second)*(source.second - target.second);
    return (int) sqrt(x+y);
}

// ---------------
int minimumMoves(int rows, int cols, int startx, int starty, int endx, int endy) {


    Vertex source = std::make_pair(startx,starty);
    Vertex target = std::make_pair(endx,endy);

    std::map<Vertex,int> distanceMap;                // distance is the minimum distance required to reach this current visited vertex.
    std::unordered_map<Vertex,Vertex> pathMap;       // pathMap is to trace the path until current visited Vertex.
    std::unordered_set<Vertex> Q;                    // Q is a set of vertices in chessboard graph.

    // initialize Graph ===> O(N^2) assuming rows = cols = n in a chessboard.
    for(int i = 0; i < rows; ++i)
    {
        for(int j = 0; j < cols; ++j)
        {
            Q.insert(std::make_pair(i,j));
        }
    }

    // Iterate over set, and then assign distanceMap and pathMap values.
    auto it = Q.begin();
    for ( auto it = Q.begin(); it != Q.end(); ++it )
    {
        distanceMap[it++] = INT_MAX;
    }

    // Make distanceMap[source] = 0;
    distanceMap[source] = 0;

    // Dijkstra's.
    // Ref 1 : finding minimum in map -- https://stackoverflow.com/questions/2659248/finding-minimum-value-in-a-map
    while(!Q.empty())
    {
        Vertex currVertex = get_min_distance_vertex(distanceMap);
        if(currVertex.first==target.first && currVertex.second==target.second){
            return countMoves(currVertex, pathMap);
        }

        Q.erase(Q.find(currVertex));
        std::vector<Vertex>neighbours = get_neighbours(currVertex,rows,cols);
        if(neighbours.empty())
            break;

        for(auto it = neighbours.begin(); it!= neighbours.end();it++)
        {
            int updateDist = distanceMap[currVertex] + distance_between_vertices(currVertex,*it);
            if (updateDist < distanceMap[*it])
            {
                distanceMap[*it] = updateDist;
                pathMap[*it] = currVertex;
            }
        }
    }


    // return all valid distances here.
    return -1; //no possible move.
}

然而,这仍然会在晦涩的文件中出现6个难以追踪的错误。在对我发现的xCode错误做了一些研究后,我发现了这个问题:

Unordered set of pairs, compilation error

此问题的解决方案应该可以解决您的问题。如果您想避免这种情况,请尝试使用hashable类型而不是pair,并修改您的语义以匹配。