-
April 22nd, 2013, 09:52 PM
#1
[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.
-
April 22nd, 2013, 10:29 PM
#2
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.
-
April 23rd, 2013, 04:10 AM
#3
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)
-
April 23rd, 2013, 07:40 AM
#4
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).
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|