0

I want to turn this single .cpp file into multiple ones but I'm having trouble doing so. I'm getting undeclared identifier and 'children' : is not a member of 'Node' compiler errors.

Here is my original entire code:

#include <iostream>
#include <vector>
using namespace std;

class Node {
public:
    Node();
    ~Node() {}
    char content();
    void setContent(char c);
    bool wordMarker();
    void setWordMarker();
    Node* findChild(char c);
    void appendChild(Node* child);
    vector<Node*> children();

private:
    char m_Content;
    bool m_Marker;
    vector<Node*> m_Children;
};

class Trie {
public:
    Trie();
    ~Trie();
    void addWord(string s);
    bool searchWord(string s);
    void deleteWord(string s);
private:
    Node* root;
};

Node::Node() 
{ 
    m_Content = ' '; m_Marker = false; 
}

char Node::content() 
{ 
    return m_Content; 
}
void Node::setContent(char c) 
{ 
    m_Content = c; 
}
bool Node::wordMarker() 
{ 
    return m_Marker; 
}
void Node::setWordMarker() 
{ 
    m_Marker = true; 
}
void Node::appendChild(Node* child) 
{ 
    m_Children.push_back(child); 
}
vector<Node*> Node::children() 
{ 
    return m_Children; 
}

Node* Node::findChild(char c)
{
    for (int i = 0; i < m_Children.size(); i++)
    {
        Node* tmp = m_Children.at(i);
        if (tmp->content() == c)
        {
            return tmp;
        }
    }

    return NULL;
}

Trie::Trie()
{
    root = new Node();
}

Trie::~Trie()
{
    // Free memory
}

void Trie::addWord(string s)
{
    Node* current = root;

    if (s.length() == 0)
    {
        current->setWordMarker(); // an empty word
        return;
    }

    for (int i = 0; i < s.length(); i++)
    {
        Node* child = current->findChild(s[i]);
        if (child != NULL)
        {
            current = child;
        }
        else
        {
            Node* tmp = new Node();
            tmp->setContent(s[i]);
            current->appendChild(tmp);
            current = tmp;
        }
        if (i == s.length() - 1)
            current->setWordMarker();
    }
}


bool Trie::searchWord(string s)
{
    Node* current = root;

    while (current != NULL)
    {
        for (int i = 0; i < s.length(); i++)
        {
            Node* tmp = current->findChild(s[i]);
            if (tmp == NULL)
                return false;
            current = tmp;
        }

        if (current->wordMarker())
            return true;
        else
            return false;
    }

    return false;
}

// Test program
int main()
{
    Trie* trie = new Trie();
    trie->addWord("Hello");
    trie->addWord("Balloon");
    trie->addWord("Ball");

    if (trie->searchWord("Hell"))
        cout << "Found Hell" << endl;

    if (trie->searchWord("Hello"))
        cout << "Found Hello" << endl;

    if (trie->searchWord("Helloo"))
        cout << "Found Helloo" << endl;

    if (trie->searchWord("Ball"))
        cout << "Found Ball" << endl;

    if (trie->searchWord("Balloon"))
        cout << "Found Balloon" << endl;

    delete trie;
}

My attempt:

node.h

#ifndef NODE_INCLUDED
#define NODE_INCLUDED

class Node {
public:
    Node();
    ~Node() {}
    char content();
    void setContent(char c);
    bool wordMarker();
    void setWordMarker();
    Node* findChild(char c);
    void appendChild(Node* child);
    vector<Node*> children();

private:
    char m_Content;
    bool m_Marker;
    vector<Node*> m_Children;
};

#endif // NODE_INCLUDED

trie.h

#ifndef TRIE_INCLUDED
#define TRIE_INCLUDED
class Trie {
public:
    Trie();
    ~Trie();
    void addWord(string s);
    bool searchWord(string s);
    void deleteWord(string s);
private:
    Node* root;
};
#endif //TRIE_INCLUDED

node.cpp

#include "node.h"
#include <iostream>
#include <vector>
using namespace std;

Node::Node() 
{ 
    m_Content = ' '; m_Marker = false; 
}

char Node::content() 
{ 
    return m_Content; 
}
void Node::setContent(char c) 
{ 
    m_Content = c; 
}
bool Node::wordMarker() 
{ 
    return m_Marker; 
}
void Node::setWordMarker() 
{ 
    m_Marker = true; 
}
void Node::appendChild(Node* child) 
{ 
    m_Children.push_back(child); 
}
vector<Node*> Node::children() 
{ 
    return m_Children; 
}

Node* Node::findChild(char c)
{
    for (int i = 0; i < m_Children.size(); i++)
    {
        Node* tmp = m_Children.at(i);
        if (tmp->content() == c)
        {
            return tmp;
        }
    }

    return NULL;
}

trie.cpp

Trie::Trie()
{
    root = new Node();
}

Trie::~Trie()
{
    // Free memory
}

void Trie::addWord(string s)
{
    Node* current = root;

    if (s.length() == 0)
    {
        current->setWordMarker(); // an empty word
        return;
    }

    for (int i = 0; i < s.length(); i++)
    {
        Node* child = current->findChild(s[i]);
        if (child != NULL)
        {
            current = child;
        }
        else
        {
            Node* tmp = new Node();
            tmp->setContent(s[i]);
            current->appendChild(tmp);
            current = tmp;
        }
        if (i == s.length() - 1)
            current->setWordMarker();
    }
}


bool Trie::searchWord(string s)
{
    Node* current = root;

    while (current != NULL)
    {
        for (int i = 0; i < s.length(); i++)
        {
            Node* tmp = current->findChild(s[i]);
            if (tmp == NULL)
                return false;
            current = tmp;
        }

        if (current->wordMarker())
            return true;
        else
            return false;
    }

    return false;
}

main.cpp

#include "node.h"
#include <iostream>
#include <vector>
using namespace std;

// Test program

#include "node.h" //is this needed?
#include "trie.h" //is this needed?
int main()
{
    Trie* trie = new Trie();
    trie->addWord("Hello");
    trie->addWord("Balloon");
    trie->addWord("Ball");

    if (trie->searchWord("Hell"))
        cout << "Found Hell" << endl;

    if (trie->searchWord("Hello"))
        cout << "Found Hello" << endl;

    if (trie->searchWord("Helloo"))
        cout << "Found Helloo" << endl;

    if (trie->searchWord("Ball"))
        cout << "Found Ball" << endl;

    if (trie->searchWord("Balloon"))
        cout << "Found Balloon" << endl;

    delete trie;
}
0rkan
  • 845
  • 2
  • 18
  • 34
Kevin Wei
  • 165
  • 11
  • Is that the exact copy of the error message? Which line does it occur on? – eerorika Aug 09 '15 at 10:46
  • 1
    Since "main.cpp" doesn't use `Node`, you shouldn't include "node.h" there. Since "trie.cpp" *does* use `Node`, you should include it there. And you should add a forward declaration, `class Node;`, at the top of "trie.h". – molbdnilo Aug 09 '15 at 10:50
  • @user2079303 The error messages are here: http://imgur.com/zVmPBTk – Kevin Wei Aug 09 '15 at 10:56
  • @molbdnilo Thanks I've done that but am still getting error messages sadly: http://imgur.com/zVmPBTk – Kevin Wei Aug 09 '15 at 10:58
  • Does this [question](http://stackoverflow.com/questions/22197030/what-is-an-undeclared-identifier-error-and-how-do-i-fix-it) solve your problem? – 0rkan Aug 09 '15 at 10:58
  • @Albert Unfortunately, no those are not my mistakes – Kevin Wei Aug 09 '15 at 11:00
  • For the code I'm seeing: `trie.cpp` should have `#include "trie.h"`, `main.cpp`should have only `#include "trie.h"` (not `#include "node.h"`), `trie.h` should have `#include "node.h"`. – 0rkan Aug 09 '15 at 11:03
  • In node.h, both vector children(); and vector m_Children; give me the error: Error 10 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int – Kevin Wei Aug 09 '15 at 11:04
  • I don't think you can use a class pointer inside of itself... Maybe that's the problem. – 0rkan Aug 09 '15 at 11:07
  • @Albert ah I see. Would I not be able to split this code into multiple files then? Sorry I'm not very well versed at C++ – Kevin Wei Aug 09 '15 at 11:08
  • 1
    Yes you will be able to! We just need to get rid of all errors. I tried to compile your code and noted you are using vector on your node.h so there should be a include: `#include ` and a `using namespace std;` for those vectors to work. – 0rkan Aug 09 '15 at 11:27

1 Answers1

1

So here is what I got working, I comment on things I have added or removed.

node.h

#ifndef NODE_INCLUDED
#define NODE_INCLUDED

#include <vector> //Class Node uses vector so it should be included
#include <iostream> //Class Node uses iostream so it should be included

class Node {
public:
    Node();
    ~Node() {}
    char content();
    void setContent(char c);
    bool wordMarker();
    void setWordMarker();
    Node* findChild(char c);
    void appendChild(Node* child);
    std::vector<Node*> children();

private:
    char m_Content;
    bool m_Marker;
    std::vector<Node*> m_Children;
};

#endif // NODE_INCLUDED

trie.h

#ifndef TRIE_INCLUDED
#define TRIE_INCLUDED

#include "node.h" //Class Trie uses Node so it should include it
#include <string> //Class Node uses string so it should include it

class Trie {
public:
    Trie();
    ~Trie();
    void addWord(string s);
    bool searchWord(string s);
    void deleteWord(string s);
private:
    Node* root;
};
#endif //TRIE_INCLUDED

node.cpp

#include "node.h"
//#include <iostream>
//#include <vector>
using namespace std;
//Here you got all includes right but they should be in the header file!

Node::Node() 
{ 
    m_Content = ' '; m_Marker = false; 
}

char Node::content() 
{ 
    return m_Content; 
}
void Node::setContent(char c) 
{ 
    m_Content = c; 
}
bool Node::wordMarker() 
{ 
    return m_Marker; 
}
void Node::setWordMarker() 
{ 
    m_Marker = true; 
}
void Node::appendChild(Node* child) 
{ 
    m_Children.push_back(child); 
}
vector<Node*> Node::children() 
{ 
    return m_Children; 
}

Node* Node::findChild(char c)
{
    for (int i = 0; i < m_Children.size(); i++)
    {
        Node* tmp = m_Children.at(i);
        if (tmp->content() == c)
        {
            return tmp;
        }
    }

    return NULL;
}

trie.cpp

#include "trie.h" //Trie.cpp should at least contain its header file

Trie::Trie()
{
    root = new Node();
}

Trie::~Trie()
{
    // Free memory
}

void Trie::addWord(string s)
{
    Node* current = root;

    if (s.length() == 0)
    {
        current->setWordMarker(); // an empty word
        return;
    }

    for (int i = 0; i < s.length(); i++)
    {
        Node* child = current->findChild(s[i]);
        if (child != NULL)
        {
            current = child;
        }
        else
        {
            Node* tmp = new Node();
            tmp->setContent(s[i]);
            current->appendChild(tmp);
            current = tmp;
        }
        if (i == s.length() - 1)
            current->setWordMarker();
    }
}


bool Trie::searchWord(string s)
{
    Node* current = root;

    while (current != NULL)
    {
        for (int i = 0; i < s.length(); i++)
        {
            Node* tmp = current->findChild(s[i]);
            if (tmp == NULL)
                return false;
            current = tmp;
        }

        if (current->wordMarker())
            return true;
        else
            return false;
    }

    return false;
}

main.cpp

//#include "node.h" //You don't use Node here, so don't include it!
                    //Keep your code simple
#include <iostream>
#include <vector>
using namespace std;

// Test program

//#include "node.h" //is this needed? Not needed because you don't use 
                    //its declarations directly here and
                    //you had it declared before
#include "trie.h" //is this needed? Yes, it is. You use that class 
                  //directly here, so it should include it
int main()
{
    Trie* trie = new Trie();
    trie->addWord("Hello");
    trie->addWord("Balloon");
    trie->addWord("Ball");

    if (trie->searchWord("Hell"))
        cout << "Found Hell" << endl;

    if (trie->searchWord("Hello"))
        cout << "Found Hello" << endl;

    if (trie->searchWord("Helloo"))
        cout << "Found Helloo" << endl;

    if (trie->searchWord("Ball"))
        cout << "Found Ball" << endl;

    if (trie->searchWord("Balloon"))
        cout << "Found Balloon" << endl;

    delete trie;
}

By the way, you should not use using namespace in header files as it is a bad practice

Community
  • 1
  • 1
0rkan
  • 845
  • 2
  • 18
  • 34
  • 2
    Don't put `using namespace` in a header file; it just leads to grief. http://stackoverflow.com/questions/5849457/using-namespace-in-c-headers – Alan Stokes Aug 09 '15 at 12:33
  • @Albert Thanks so much! So for good practice, 1. "Library Includes" should go in the headers only 2. using namespace should be in .cpp's if needed – Kevin Wei Aug 09 '15 at 21:21