-5

I have written code (reference below) to count number of moves from a start Vertex to an end vertex.

Sparing the validation of logic of the code, I'm a little overwhelmed by the compile errors I'm getting for this code. I think I can understand why the errors are happening, but I'm unsure about the best way to fix them. So I could really use some help there.

The lines that give me compile errors, the reasons I think why they're there, and what I have gleaned so far are listed below.

Number 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;      

The error I get above is

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

I've already declared the type Vertex like so

typedef pair<int,int> Vertex; 

So what's the mistake here?

Number 2

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

The error occurs when I insert the pair into the unordered_set.

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

Number 3

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

Error:

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

How do I properly declare the iterator for this, if auto doesn't apply?

Number 4

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

Error:

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

Number 5

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

Error :

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

I understand there needs to be some sort of an operator overloading here? How would I implement this?

Number 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}’)
}

For this, again, I'm not sure why the error exists when I'de already declared that pmap is of type unordered_map<Vertex,Vertex> pmap and typedef pair<int,int> Vertex;

Full code for reference

// ------ 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.
}
Raaj
  • 1,180
  • 4
  • 18
  • 36
  • 1
    You should resolve compiler errors as they appear, not let them accumulate until your are overwhelmed. – Beta Mar 05 '17 at 22:51
  • Yes, I'm just not sure how to fix them when I've written custom data types before and not had these errors, and considering there'e no reference. If you could point out some references to understanding these errors, would be helpful :) – Raaj Mar 05 '17 at 22:53
  • I'm voting to close this because it's asking too many questions. You need to solve errors one by one, because occasionally solving one problem solves the rest. In this case, you seem to have a lot of problems with `std::unordered_map`. You really should've reduced your code to a [mcve]. Are you compiling in C++11?, because [`std::unordered_map` wasn't introduced till C++11](http://en.cppreference.com/w/cpp/container/unordered_map) – Tas Mar 05 '17 at 23:38
  • I understand that, but that's exactly the question I have... how do I resolve the compile error syntactically? I have these errors with unordered_map and set, and I'm compiling them with C++11 compiler.. But these errors exist nevertheless. Would code review be a better place to ask this question? – Raaj Mar 06 '17 at 00:19
  • What are you using as a key in this line? `std::unordered_map Q;` unordered_maps need a key. – パスカル Mar 06 '17 at 02:01
  • Hi @PascalDescollonges, the line is `unordered_set Q` so it's a set, not a map. – Raaj Mar 06 '17 at 15:11
  • Oh. Sorry. I missed that. – パスカル Mar 06 '17 at 22:59

1 Answers1

1

After cleaning up the code and fixing obvious syntax errors, adding includes, and so on, here is a copy:

#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.
}

However, this still spews 6 hard-to-trace errors in obscure files. After doing some research on the xCode errors I found, I found this question:

Unordered set of pairs, compilation error

The solution in this question should solve your problem. If you would like to avoid this, try just using a hashable type instead of a pair, and modifying your semantics to match.

Community
  • 1
  • 1
パスカル
  • 479
  • 4
  • 13