CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2011
    Location
    Tennessee
    Posts
    46

    [RESOLVED] Trees (Maps) problem

    Hello, I am trying to use a red-black tree, STL Map, to read in a file that counts the words while ignoring punctuation and converting all words to lowercase. My problem occurs when I try to print and nothing outputs to the screen. I think it has something to do with my for loop in my print function. I have looked over it many times along with some of my fellow students and everyone seems to think it too should be working. I probably have done something stupid and really would appreciate an expert or someone who knows this more than I do to point out my mistake, anything, thanks.

    Header file
    Code:
    #ifndef MAP_H
    #define MAP_H
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    class Map
    {
    public:
    	//map<string, int> words;
    	void inputFile(char inputfile[]);// read file
    	void insertTree(string new_word, map<string, int> &tree);//insert
    	void print(map<string, int> &tree);// print
    };
    #endif
    Implementations
    Code:
    #include <iostream>
    #include <fstream>
    #include <map>
    #include <string>
    #include "Map.h"
    
    using namespace std;
    
    void Map::inputFile(char inputfile[])// read file
    {
    	ifstream infile;
    	infile.open(inputfile);
    	
    	int j;
    	char lowercase;
    	map<string, int> words;
    	string str_1, str_2;
    	
    	while(infile >> str_1)
    	{
    		for(int i = 0, a = 0; i < str_1.length(); i++)
    		{
    			char &letter = str_1[i];
    			
    			if(letter < 'A' || (letter > 'Z' && letter < 'a') || letter >'z') // only alphabet characters
    			{
    				for(int j = 0; j < str_1.length(); j++)
    				{
    					str_1[j] = tolower(str_1[j]); // make all lowercase
    				}
    
    				str_2 = str_1.substr(a, i - a);
    				a = i +1;
    				
    				if(str_2.length() > 0)
    				{
    					insertTree(str_2, words); // insert into the tree
    				}
    			}
    		}
    	}
    	infile.close(); 
    }
    void Map::insertTree(string new_word, map<string, int> &tree)
    {
    //	cout << "Insert" << endl;
    	if(tree.find(new_word) == tree.end()) //Word is not currently in the tree
    	{
    		tree[new_word] = 1;
    	}
    	else //Word is in the tree 
    	{
     		tree[new_word] = tree[new_word] + 1;
     	}
    }
    void Map::print(map<string, int> &tree)// print
    {
    //	cout << "Out print" << endl;
    	for (map<string, int>::iterator print_it = tree.begin(); print_it != tree.end(); ++print_it)
    	{
    //		cout << "printing" << endl;	
    		cout << print_it -> first << " => " << print_it -> second << '\n'; //.first is the data member, .second is the data.
    	}
    }
    Driver
    Code:
    #include <iostream>
    #include <map> //Map
    #include <string> //String
    #include "Map.h"
    
    using namespace std;
    
    //void incrementTree(string new_word, map<string, int> &tree);
    //void printTree(map<string, int> &tree);
    
    
    int main() {
      int choice;
      char inputfile[100];
      //The key (index for the tree) is a string value, the data we store in the tree is an integer value.
      //Note that unlike the example from class, we are distinguishing here between the key and data.
      map<string, int> words;
    	
      Map mapper;
      
    Menu:
      cout << "********Menu********" << endl;
      cout << "1.) Please enter a file for input. " << endl;
      cout << "2.) Print" << endl;
      cout << "3.) Exit" << endl;
      
      cout << "Please make a choice: ";
      cin >> choice;
    
      while(choice <= 3 || choice >= 1)
      {
    	switch(choice)
    	{
    		case 1 : cout << "Filename: ";
    		         cin >> inputfile;
    			 mapper.inputFile(inputfile);
    			 break;
    		case 2 : mapper.print(words);
     			 break;
    		case 3 : cout << "Exiting." << endl;
    			 goto Exit;
    			 break;
    		default: cout << "ERROR!...Re-prompting input." << endl;
    			 break;
    	}
    	goto Menu;
      } 
    
     // incrementTree("the", words);
     //incrementTree("quick", words);
    // incrementTree("brown", words);
      //incrementTree("fox", words);
      //incrementTree("jumped", words);
      //incrementTree("over", words);
      //incrementTree("the", words);
      //incrementTree("lazy", words);
      //incrementTree("dog", words);
    
      //printTree(words);
    
    Exit:  
    
      return 0;
    }
    
    /*
    void incrementTree(string new_word, map<string, int> &tree) {
      //Word is not currently in the tree
      if(tree.find(new_word) == tree.end()) {
        tree[new_word] = 1;
      }
      //Word is in the tree
      else {
        tree[new_word] = tree[new_word] + 1;
      }
    }
    
    
    void printTree(map<string, int> &tree) {
      for (map<string, int>::iterator print_it=tree.begin(); print_it!=tree.end(); ++print_it)
        //.first is the data member, .second is the data.
        cout << print_it->first << " => " << print_it->second << '\n';
      
    }*/
    Thanks to all in advance.

  2. #2
    Join Date
    Oct 2011
    Location
    Tennessee
    Posts
    46

    Re: Trees (Maps) problem

    Nevermind I solved it with a helper function for print. Thanks all for your time if anyone wants email me or PM me and I will let you know how I did it. Peace, Out.

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [RESOLVED] Trees (Maps) problem

    When something doesn't work as it should rather than trying to guess the problem and just trying things 'to see if they work', use the debugger to trace through the code to see where it deviates from what was expected. You should become as familiar with the debugger as writing/compiling programs. Debugging programs is a skill that has to be learnt. Some of us who have been around programming for a long time seem to spend half our life in the debugger!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: [RESOLVED] Trees (Maps) problem

    There are a few issues with your code:

    1) Although this does not affect your program, you
    should not put "using namespaec std;" in your
    header file. It can cause name clash problems.
    You should fully qualify the variable type. Example:

    Code:
    void print(std::map<std::string, int> &tree);// print
    2) print() does not modify any variable in the Map class.
    Therefore it should be a const function:

    Code:
    void print(std::map<std::string, int> &tree) const; // print
    3) additionally, print does not modify the passed argument,
    so you should pass by const reference, not by reference.
    You would need to use const_iterator instead of iterator
    in the function.

    Code:
    void print(const std::map<std::string, int> &tree) const; // print
    4) in main, you call:

    Code:
    mapper.print(words);
    But words is a local variable to main that is never modified.
    That is why you did not see any output.

    5) in your header, you comment out the line:
    Code:
    //map<string, int> words;
    And instead you have "words" a local variable in the inputfile
    function. I think you should keep the member variable words
    and remove the local variable from inputfile. You would not
    need to pass the map to print() and insertTree. Just make
    sure those functions use the member variable, words.

    6) There is nothing wrong with the way you coded insertTree,
    but it can be simplified to one line (but it requires a little
    more advanced knowledge on how operator [] works for std::map).

    Code:
    ++tree[new_word];

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured