0

Im on my journey to refresh my c++ skills, for upcoming project in 2-3 weeks.

Im implementing a command line program that given input adjacency list 1>2;2>3;3>1,3,4 were ">" actually means -> path to. Will generate a internal adjacency matrix, then using Dijkstra print the shortest paths.

Im while implementing Dijkstra, Im suddenly getting a in short "unresolved external symbol "public: __thiscall Node::Node(void)"

Here is the whole error msg:

Error   error LNK2019: unresolved external symbol "public: __thiscall Node::Node(void)" (??0Node@@QAE@XZ) referenced in function "void __cdecl Dijkstra(class std::vector<class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::allocator<class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > > > const &)" (?Dijkstra@@YAXABV?$vector@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@V?$allocator@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@@2@@std@@@Z) C:\Users\ary\Documents\visual_studio_code\examples\CourseraC_plus_plus_for_C_1\week2\shortest_path'\shortest_path'\shortest_path'.obj   shortest_path'

Here is main class:

Here is the main entry cpp:

// shortest_path'.cpp : Defines the entry point for the console application.

#include "stdafx.h"

//This software takes in 2-dimensional vertices {x,y} as input and constructs a adjacency matrix internally. 
//Then the software will use shortest path algorithm to display all the shorterst paths from a 
//start node to other nodes. 


#include <iostream>
#include <string>
#include <vector>
#include <map>
#include "Node.h"
using namespace std;

//signature for menu function 
void menu();
//sub menu option and capture input for vertices
void inputVerticesSubMenu();
//split the vertices into tokens
vector<string> splitVerticesInputString(const string&, char);
//create 2d arrat to represent adjacency matrix
vector<vector<string>> adjacencyMatrix(const vector<string>&);
//shortest path 
void Dijkstra(const vector<vector<string>>& adjacency);

//visited Nodes
vector<Node*> visited;
//not visited 
vector<Node*> notVisited;

int numberOfUniqueNodes = 0;
int main()
{

    int input;

    menu();
    cin >> input;
    while (input != -1)
    {

        //what option was selected
        switch (input)
        {
            cout << "input: " << input;
        case 1:
            cout << "case 1" << endl;
            inputVerticesSubMenu();
            break;
        case 2:
            cout << "case 2" << endl;
            break;
        case 3:
            cout << "case 3" << endl;
            input = -1;
            return 0;
        default:
            cout << "invalid option!" << endl;
            menu();
            cin >> input;
            break;
        }//end option switch

        menu();
        cin >> input;


    }

};

void menu()
{
    cout << "" << endl;
    cout << "1) enter vertices" << endl;
    cout << "2) compute shortest path via Dijkstra (use option 1 first)." << endl;
    cout << "3) exit" << endl;
}


void inputVerticesSubMenu()
{
    cout << "Example if you have a graph with vertices 1,2,3." << endl;
    cout << "If 1 points to 2, and 2 points to 3, and 3 points back to 1 & itself." << endl;
    cout << "Then enter 1>2;2>3;3>1,3. Then press Enter when done." << endl;
    cout << "This will create a internal adjacency matrix which will be printed as a check." << endl;
    cout << "Enter vertices:" << endl;
    string inputVertices;
    cin >> inputVertices;
    cout << "Please enter number of unique nodes (For example  1>2;2>3;3>1,3 has 3 nodes):" << inputVertices << endl;
    cin >> numberOfUniqueNodes;

    vector<string> tokens = splitVerticesInputString(inputVertices, ';');

    string token;
    map<string, string> uniqueNodes;

    vector<vector<string>> adjacency = adjacencyMatrix(tokens);
    cout << "adjacency matrix:" << endl;
    Dijkstra(adjacency);



    cout << "Then select Option 2 to start Dijkstra computation!" << endl;

}//end inputVerticesSubMenu()

vector<string> splitVerticesInputString(const string& inputVertices, char delimiter)
{
    vector<string> tokens;
    string token;
    int start = 0;
    int end = 0;
    for (int i = 0; i <= inputVertices.length(); i++)
    {

        //cout << inputVertices[i] << endl;
        if (inputVertices[i] == delimiter || i == inputVertices.length())
        {
            end = i;
            int length = (end - start);
            token = inputVertices.substr(start, length);

            tokens.push_back(token);
            start = end + 1;


        }//ednd if token is found


    }//end for 

    return tokens;
}

vector<vector<string>> adjacencyMatrix(const vector<string>& tokens)
{

    vector<vector<string>> adjacency;
    string token;

    //create row of vectors based on number of numberOfUniqueNodes
    for (int c = 0; c < numberOfUniqueNodes; c++)
    {
        //the vector should be of size numberOfUniqueNodes & initialized to 0 
        vector<string> rowVector(numberOfUniqueNodes, "0");
        adjacency.push_back(rowVector);
    }//end loop 


    //parse tokens in vectors ,ane create a simulated matrix in vector<vector<string>>
    for (int i = 0; i < tokens.size(); i++)
    {
        //1st split from to get originating node , then ending connection nodes
        token = tokens.at(i);
        //cout << "token:" << token << endl;

        std::size_t found = token.find('>');
        if (found != std::string::npos)
        {
            string fromNode = token.substr(0, found);
            string neighborNodes = token.substr(found + 1, token.size() - found);
            cout << "vertice=" << fromNode << ">" << neighborNodes << endl;
            int row = atoi(fromNode.c_str()) - 1;
            vector<string> row_vector = adjacency.at(row);
            //parse the neighborNodes string using 
            vector<string> columns = splitVerticesInputString(neighborNodes, ',');
            for (int k = 0; k < columns.size(); k++)
            {
                int offset = atoi(columns.at(k).c_str());
                //TODO : columns
                row_vector.at(offset - 1) = "1";
            }
            //persist back
            adjacency.at(row) = row_vector;
        }
        else
        {
            cout << "vertice=" << token << endl;
        }


    }//end

    return adjacency;
}//end vector<vector<string>> adjacencyMatrix(const vector<string>& tokens)


void Dijkstra(const vector<vector<string>>& adjacency)
{
    Node *currentNode = new Node(); 

    //print the adjacency matrix for the matrix & initialize univisited vector
    for (int r = 0; r < adjacency.size(); r++)
    {

            //instantiate new Node from adjacency matrix 
            currentNode->setLabel(std::to_string(r + 1));
            currentNode->setWeight(1);

        vector<string> row_vector = adjacency[r];
        for (int c = 0; c < row_vector.size(); c++)
        {
            //add neighbors
            std::cout << row_vector.at(c);
            if (row_vector.at(c) == "1")
            {
                Node *neighbor = new Node();
                neighbor->setLabel(std::to_string(c + 1));
                neighbor->setWeight(1);
                //set prev link to parent/originating Node 
                neighbor->setPrev(currentNode);

                currentNode->addNeighborNode(neighbor);
            }

        }
        //add to notVisited vector 

        notVisited.push_back(currentNode);

        std::cout << endl;
    }//end 

    cout << "Linked list of nodes" << endl; 


}//end 

Node header:

    #ifndef NODE_H
    #define NODE_H
    #include <string>
    #include <vector>
    using namespace std;
    class Node
    {
    public:
        Node();
        Node(string label);
        ~Node();
        void setLabel(string value);
        string getLabel();
        void setWeight(int value);
        int getWeight(); 
        void addNeighborNode(Node* node);
        vector<Node*> getNeighbors(); 
        void setPrev(Node* node);
        Node* getPrev(); 
        Node& operator=(const Node& other);

    private:
        string _label; 
        int _weight =0; 
        vector<Node> _neighbors; 
        Node* _prev; 
    };
    #endif 

Node implementation cpp:

#include "Node.h"

Node::Node()
{

}

Node::Node(string label)
{
_label = label;
}

Node::~Node()
{

}

/*
void setLabel(string value);
    string getLabel();
*/

Node::setLabel(string value)
{
    _label = value; 
}

string Node::getLabel()
{
    return _label; 
}
/*
void setWeight(int value);
    int getWeight(); 
    */
Node::setWeight(int value)
{
    _weight = value; 
}

int Node::getWeight()
{
    returtn _weight;
}

/*
void addNeighborNode(Node& node);
    vector<Node> getNeighbors(); */

Node::addNeighborNode(Node* node)
{
    _neighbors.push_back(node);
}

vector<Node*> ode::getNeighbors()
{
    return _neighbors;
}
/*
    void setPrev(Node& node);
    Node& getPrev(); 
*/
Node::setPrev(Node* node)
{
    _prev = node; 
}

Node* Node::getPrev()
{
    return *_prev; 
}

Node& operator=(const Node& other) // copy assignments
{
    if (this != &other) { // self-assignment check expected
       _label = other._label;
       _weight = other._weight; 
       _prev = other._prev; 
       _neighbors = other._neighbors;

    }
    return *this;
}

This error occurs when I try to instantiate a pointer of type Node in the 1st line after the void Dijkstra(const vector<vector<string>>& adjacency) function signbature Node *currentNode = new Node();. Naturally I would think Node() constructor is not implemented in cpp but it is, then I looked at other functions & they were also ok.

I also know Dijkstra is not completed, Im waiting to resolve this issue 1st.

Any help will be appreciated.

Thanks

cyber101
  • 2,822
  • 14
  • 50
  • 93
  • There are all kinds of problems with this code that will make it fail to compile (missing return type declaration, mismatched types etc.) Once you've fixed all of those just make sure to include the Node cpp file in your project and you should be good. – mnistic Mar 18 '18 at 22:48
  • 1
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – 1201ProgramAlarm Mar 18 '18 at 22:59

0 Answers0