Hey there folks. I am trying to write a program that will take in a paragraph file, and compare it against a "Dictionary" text file, which is being inserted into a Binary Search Tree. Here's what I've got so far:

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>
#include <stack>
using namespace std;

class Node;
stack<string> theStack_;
typedef Node * nodePtr_;

class Node
{
public:
    string data_;
    nodePtr_ left_;
    nodePtr_ right_;
    Node() : left_(NULL), right_(NULL), data_("") { }
};


class BST
{
private:
    nodePtr_ root_;
public:
    BST() : root_(NULL) { }

    void insert(string data)
    {
        insert(data, root_);
    }
    void insert(string data, nodePtr_ &node)
    {
        if (node == NULL)
        {
            node = new Node();
            node->data_ = data;
        }
        else if (data < node->data_)
        {
            // Traverse left sub tree
            insert (data, node->left_);
        }
        else if ( data > node->data_)
        {
            // Traverse right sub tree
            insert (data, node->right_);
        }
        else
        {
            // Node exists
            cout << "Node value: " << node->data_ << " already exists!" << endl;
        }
    }

    bool spellCheck(string data)
    {
        bool broken = spellCheck(data, root_, 0);
        return broken;
    }
    bool spellCheck(string data, nodePtr_ &node, int indent)
    {
        if (node == NULL)
        {
            return false; // Empty
        }
        else if (data == node->data_)
        {
            return true;
        }
        else if (data < node->data_)
        {
            return true;
        }
        else
        {
            return spellCheck(data, node->right_, indent+8);
        }
    }
    // Recursive printing
    void printTree( ostream &output, nodePtr_ &node, int indent)
    {
        if (node != NULL)
        {
            printTree (output, node->right_, indent+8);
            output << setw(indent) << node->data_ << endl;

            printTree (output, node->left_, indent+8);
        }   
    } 
    void removeNode (string data)
    {
        bool found_ = false;
        nodePtr_ node = root_;
        nodePtr_ parent_ = NULL;


        while (!found_ && (node != NULL))
        {
            if (data < node->data_)
            {
                // Go left
                parent_ = node;
                node = node->left_;
            }
            else if (data > node->data_)
            {
                // go right
                parent_ = node;
                node = node->right_;
            }
            else
            {
                // found!
                found_ = true;
            }
        }

        if (!found_)
        {
            return;
        }

        // find the successor
        if ((node->left_ != NULL) && (node->right_ != NULL))
        {
            // Goto left most node
            nodePtr_ successor = node->right_;
            parent_ = node;
            while (successor->left_ != NULL)
            {
                parent_ = successor;
                successor = successor->left_;
            }
            node->data_ = successor->data_;
            node = successor;
        }

        // now we can delete the node with either one child or no child
        nodePtr_ subTree = node->left_;

        if (subTree == NULL)
        {
            subTree = node->right_;
        }
        if (parent_ == NULL)
        {
            // delete root node
            root_ = subTree;
        }
        else if (parent_->left_ == node)
        {
            // delete a node with left subtree
            parent_->left_ = subTree;
        }
        else
        {
            // Delete a node with a right subtree
            parent_->right_ = subTree;
        }
        delete node;
    }






    // Trying to sort
    bool treeContains( nodePtr_ &node, string item, int indent)
    {
        if (node == NULL)
        {
            return false; // tree is empty
        }
        else if (item == node->data_)
        {
            return true;
        }
        else if (item < node->data_)
        {
            return true;
        }
        else 
        {
            return treeContains( node->right_, item, indent+8);
        }
    } 
    friend ostream& operator<<( ostream &output, BST &bst);
};
ostream& operator<< (ostream &output, BST &bst)
{
    bst.printTree(output, bst.root_, 0);
    //bst.printTree(bst.root_);
    return output;
}










int main()
{
    BST bst;
    string line;
    ifstream dictionaryFile("dictionary.txt");
    ifstream paragraphFile("paragraph.txt");
    int fileSize = 0; // Size of paragraph
    int dictLoaded = 0; // 0 - not loaded, 1 - loaded, 1< - done
    bool brokenWord = false;
    string search_for = " ";

    if (dictLoaded == 0)
    {
        if (dictionaryFile.is_open())
        {
            while (!dictionaryFile.eof())
            {
                getline(dictionaryFile,line);
                bst.insert(line);
            }
        }
        dictionaryFile.close();
        dictLoaded = 1;
    }

    if (dictLoaded == 1)
    {
        if (paragraphFile.is_open())
        {
            while (dictLoaded >> line)
            {
                if (line == search_word)
                {
                }
                //getline(paragraphFile,line);
                //brokenWord = bst.spellCheck(line);
                //if (brokenWord)
                //{
                //    cout << "Bad word! ";
                //}
                //else
                //{
                //    cout << "No bad words!";
                //}
            }
        }
        dictLoaded = 2;
        paragraphFile.close();
    }
    cout << bst << endl;
    return 0;
}

As you can see, my BST is working just fine, loading the dictionary in and is able to show it. My problem lies here, I planned on searching through the paragraph file word for word, and comparing that word against the dictionary tree. I had the idea of doing this with a stack, putting the words into a stack, checking it, and tossing the word if it's okay. Other wise return the word to the client code, and display the error.

Around line 240 I'm starting to try my search, though I don't know the best way to find the word, right now I was just searching for spaces, and then... blank. =(

Thanks for all your help!

Dani AI

Generated

— the BST insertion and printing look fine; the trouble is in three places: the file-reading loop, the search routine logic, and token normalization (punctuation/case). was right to recommend reading token-by-token, and correctly pointed out the undefined search_word and the wrong stream used in the paragraph loop.

First, read the paragraph word-by-word, normalize each token, then check the tree immediately. A stack is unnecessary and will only reverse or complicate processing. Normalization should remove punctuation and map to a consistent case so dictionary entries and paragraph tokens match.

A minimal normalization and recursive search example (replace or adapt to your types) — strip non-letters and lowercase before lookup:

std::string normalize(std::string s) {
    std::string out;
    for (unsigned char c : s) {
        if (std::isalpha(c)) out.push_back(std::tolower(c));
    }
    return out;
}

bool contains(nodePtr node, const std::string &key) {
    if (!node) return false;
    if (key == node->data_) return true;
    return (key < node->data_) ? contains(node->left_, key)
                               : contains(node->right_, key);
}

Then, in the main loop, read tokens from the paragraph stream, normalize, skip empty tokens, and call contains. If a word isn’t found, report it. While debugging, print tokens after normalization to confirm punctuation and case are handled as expected.

Optional: for simpler code and much faster lookups, load the dictionary into std::unordered_set<std::string> (normalized) instead of a hand-rolled BST. Also make sure dictionary lines are trimmed/lowercased when inserted (no trailing spaces or blank lines). These changes will fix the incorrect boolean logic in your search, eliminate the search_word/stream bugs, and make the spell-check reliable.

Recommended Answers

All 3 Replies

You could just read the file one word at a time with filestreams instead of using getline(), it would save you a lot of time.:

std::ifstream in ( "myfile" );

if ( in ) 
{
  std::string word;
  while ( in>> word ) 
   {
       spellCheck(word);

   }
}

If you want your line numbers visible, you should put your code between [code=cplusplus] [/code] tags

Niek

Yeah... I figured that out two seconds before I received the email saying you replied.

Thanks bud, much <3

how do make this work? You haven't declared search_word in main and haven't defined the operator for doing this
dictLoaded >> line

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.