I was asked to create a program to find word frequencies, word length in a text file. I am able to use map to do the frequencies part but don't know how to sort the the output accordingly to the length of the words. The example output that I should get is

1 a. 362
i. 157

2 an. 122
at. 201

3 add. 2
age. 1

int main(void)
{
    static const char* file = "demo.txt";
map<string, unsigned int> wcount;

    {
    ifstream fileStream(file);
        if (fileStream.is_open())
        while (fileStream.good())
        {string word;
            fileStream >> word;
            if (wcount.find(word) == wcount.end())
                wcount[word] = 1;

            else 
                wcount[word]++;
        }
        else  
        {
            cerr << "Unable to open file." << endl;
            return EXIT_FAILURE;
        }

        display(wcount);
    }

    return EXIT_SUCCESS;
}

Recommended Answers

All 5 Replies

As a general approach, I would start by iterating through the map completely, displaying the words of length 1. Then go though again, looking for length 2 words, etc.
As you make a pass, keep track of the longest length that exists, when you display the words of that length, you are done.

Or, you could export the key words to an array or vector, sort them by length, and use that to key into the map for display.

Can you show me an example of the second approach on how you'd do it ?

Well, I haven't done much of anything with maps up to now, but you piqued my interest.

Here's a beginning for your display that copies the words to a vector. I'll leave it to you to sort the vector by size (rather than alpha order), while keeping the original ordering.

void display( map<string, unsigned int> wcount )
{
    vector<string> words;

    for (map<string, unsigned int>::iterator it=wcount.begin(); it!=wcount.end(); ++it)
    {
        words.emplace_back( it->first) ;
    } 

    //this just displays the vector content so you can see it worked
    for ( unsigned int i = 0; i < words.size(); ++i)  
        cout << words[i] << endl;

}

Hi like vmanes said, your best option is to transverse the map (a sort of hash table) and output base on the lenght of words, and moving the map data into a vector is probably the easiest way of doing it.

I would suggest that because a map cannot be sorted, see if using a binary tree could work better for you. If you implement a binary search tree then you can have the data already sorted by the time you finish reading the file and then just transverse the tree once and have the output the way you need it

here are a couple links that could help you setting up a binary search tree
http://www.cprogramming.com/tutorial/lesson18.html
http://www.bogotobogo.com/cplusplus/binarytree.php

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.