Thread: Need help on this exercise

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    18

    Need help on this exercise

    I have been trying to learn C++ using the book Accelerated C++. Right now, I'm on chapter 3, and I'm stuck at an Exercise portion. The problem is like this:

    3-3 Write a program to count how many times each distinct word appears in its input. Right now, I have this:

    Code:
    #include <algorithm>
    #include <iomanip>
    #include <ios>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::cin;     using std::sort;
    using std::cout;    using std::string;
    using std::endl;    using std::streamsize;
    using std::setprecision;    using std::vector;
    
    int main()
    {
        //Tell the user to input numbers
        cout << "Enter a message, then give an end-of-file signal: ";
    
        //Create a vector of string type to hold the input
        vector<string> input;
        string x;
    
        while(cin >> x)
        {
            input.push_back(x);
        }
    
        //create a size_type type to hold the size of the input container
        vector<string>::size_type size;
        size = input.size();
    
        //test to see if the user has input anything
        if(size == 0)
        {
            cout << "You haven't input anything yet. Please try again.";
            return 1;
        }
    
        vector<int> count;
    
        for(int y = 0; y != size; ++y)
        {
    
        }
    
    
        return 0;
    }
    I don't know what to put inside the for loop; specifically, I don't know what to code so that every index of the vector can be compared to every other index.

    If it helps to know, so far I have learned about strings, looping, and vector, among others, in this and the previous chapters.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    You told yourself the answer, so I'm not really sure how else to put it.
    The solution you're probably looking for has nested for loops. Compare every x to every y.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Well you could use the count algorithm. But chances are that's not the solution their looking for in chapter 3. (Though I'd be impressed if they were).

    You want to first determine the set of unique words in the input, and only then count the number of occurrences.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    If you don't "have" to use a vector, perhaps a different STL container might be useful...
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    18
    I don't think it's looking for count algorithm (whatever count algorithm suppose to be) since I don't recall learning it. The book does mention about sort function though in this chapter (chapter 3), though.

    Since this chapter is about "Working with batches of data," and the book introduces the vector container, I do think that I have to use it.

    Anyway, I still had trouble figuring it out even with a nested for loop, but I think I finally got it.

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::cin;     
    using std::cout;    using std::string;
    using std::endl;    using std::vector;
    
    int main()
    {
        //Tell the user to input numbers
        cout << "Enter a message, then give an end-of-file signal: ";
    
        vector<string> input;
        string x;
    
        while(cin >> x)
        {
            input.push_back(x);
        }
    
        //create a size_type type to hold the size of the input container
        vector<string>::size_type size;
        size = input.size();
    
        //test to see if the user has input anything
        if(size == 0)
        {
            cout << "You haven't input anything yet. Please try again.";
            return 1;
        }
    
        int count = 1;
    
        for(int y = 0; y != size - 1; ++y)
        {
            for(int z = y + 1; z != size; ++z)
            {
                if(input[y] == input[z])
                {
                    ++count;
                }
            }
        }
    
        return 0;
    }
    This exercise is more troublesome than I originally thought, though. Now that I'm able to compare each index of the container to every other index, I'm having trouble of reporting the result, which is to report each distinct word, as well as how many times the word appears.

    Anyway, I'm going to stop (to go to bed) and do this later. Just want to ask if what I have got so far is correct.
    Last edited by tiachopvutru; 05-19-2008 at 07:19 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    The book does mention about sort function though in this chapter (chapter 3), though.
    If you sort, you would not need to use nested for loops. A single for loop would then suffice (and for a large collection of elements it would be more efficient, too).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    May 2008
    Posts
    18
    Quote Originally Posted by laserlight View Post
    If you sort, you would not need to use nested for loops. A single for loop would then suffice (and for a large collection of elements it would be more efficient, too).
    Well, according to what's in the book:

    sort(b, e) - Rearranges the elements defined by the range [b, e) into nondecreasing order. Defined in <algorithm>.

    So I have assumed that it would only work with numbers. If I sort the elements of a vector<string>, what would happen?

    EDIT: Well, I have been spending more than an hour or a couple of hours trying to figure out how to show the result correctly, but still stuck.

    For example, if I have a phrase "these two animals look like two monkeys," then two would appear twice. My program does display "two" and indicates that it appears twice, but then my program would display another "two" and indicates it as appearing once, so the output to that phrase becomes:

    Code:
    these	1
    two	2
    animals	1
    look	1
    like	1
    two	1
    (the format doesn't look that neat, but the output is the same)

    Here's my code right now:
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::cin;
    using std::cout;    using std::string;
    using std::endl;    using std::vector;
    
    int main()
    {
        //Tell the user to input numbers
        cout << "Enter a message, then give an end-of-file signal: ";
    
        vector<string> input;
        string x;
    
        while(cin >> x)
        {
            input.push_back(x);
        }
    
        //create a size_type type to hold the size of the input container
        vector<string>::size_type size;
        size = input.size();
    
        //test to see if the user has input anything
        if(size == 0)
        {
            cout << "You haven't input anything yet. Please try again.";
            return 1;
        }
    
        int count = 1;
    
        for(int y = 0; y != size - 1; ++y)
        {
                for(int z = y + 1; z != size; ++z)
                {
                    if(input[y] == input[z])
                    {
                        ++count;
                    }
                }
            cout << input[y] << "   " << count << endl;
            count = 1;
    
        }
    
        return 0;
    }
    I do know where the problem is but do not know how to fix it. I have tried several ideas, but still met dead-ends in the end.

    Thank you in advance
    Last edited by tiachopvutru; 05-19-2008 at 07:35 PM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Well, according to what's in the book:

    sort(b, e) - Rearranges the elements defined by the range [b, e) into nondecreasing order. Defined in <algorithm>.

    So I have assumed that it would only work with numbers. If I sort the elements of a vector<string>, what would happen?
    Try it on a randomly ordered vector of strings, then print the vector of strings and see the difference
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    18
    Quote Originally Posted by laserlight View Post
    Try it on a randomly ordered vector of strings, then print the vector of strings and see the difference
    Aha! They arrange the words into alphabetical order in the "nondecreasing" order. Therefore, the words that are identical get grouped next to each other. The author should have told me this earlier...

    Anyway, my run is successful, so I think I finally got it. Here's my code:

    Code:
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::cin;     using std::sort;
    using std::cout;    using std::string;
    using std::endl;    using std::vector;
    
    int main()
    {
        //Tell the user to input numbers
        cout << "Enter a message, then give an end-of-file signal: ";
    
        vector<string> input;
        string x;
    
        while(cin >> x)
        {
            input.push_back(x);
        }
    
        //create a size_type type to hold the size of the input container
        vector<string>::size_type size;
        size = input.size();
    
        //test to see if the user has input anything
        if(size == 0)
        {
            cout << "You haven't input anything yet. Please try again.";
            return 1;
        }
    
        sort(input.begin(), input.end());
        int count = 1;
    
        for(int y = 0; y != size - 1; ++y)
        {
            if(input[y] != input[y+1])
                cout << input[y] << "   " << 1 << endl;
            else
            {
                ++count;
                ++y;
                while(input[y] == input[y+1])
                {
                    ++count;
                    ++y;
                }
                cout << input[y] << "   " << count << endl;
                count = 1;
            }
        }
    
        return 0;
    }
    I have a question, though. When I first compile this new code, there weren't the "#include <algorithm>" and "using std::sort" there, but the compile and the run were still successful. How?

    I also have couple more questions to ask:
    if int x = 1, what's the difference between x++ and ++x? I have tried both and they both print out 2 when I use cout. The book mentions that x++ has higher priority than ++x, and its explanation of the two is as followed:
    x++ : Increments x, returning the original value of x.
    ++x : Increments x, returning the incremented value.

    Why is using "using namespace std" not advisable? (Nevermind if the explanation is more than I can understand from what I know so far...)
    Last edited by tiachopvutru; 05-19-2008 at 11:23 PM.

  10. #10
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    using a map<string,unsigned int> would be much simpler!

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >> When I first compile this new code, there weren't the "#include <algorithm>" and "using
    >> std::sort" there, but the compile and the run were still successful. How?

    It really shouldn't have, but the only reason I can think of is "compiler forgiveness." The compiler may include a bunch of headers on its own when you build your executable. It's also likely that the compiler looked up sort because it was passed arguments located in the std namespace. In this case, since the iterators returned by begin() and end() were std iterators, the compiler looked in the std namespace for a sort function and used it. One of the names for this is Koenig lookup.

    Well that's my best guess anyway. If your compiler had been switched to "picky" mode, it would have thrown up a diagnostic.

    >> if int x = 1, what's the difference between x++ and ++x?

    The book is right. However, the difference only really matters if you are depending on the return value of the increment, or copying x is performance expensive. Most of the time, neither of these are the case, but when you learn about iterators it should make more sense. You can also write some algorithms that depend on how you increment x, such as a partition:
    Code:
    int jsw_partition ( int a[], int first, int last )
    {
      int pivot = first;
    
      while ( first < last ) {
        if ( a[first] <= a[last] )
          jsw_swap ( &a[pivot++], &a[first] );
    
        ++first;
      }
    
      jsw_swap ( &a[pivot], &a[last] );
    
      return pivot;
    }
    >> Why is using "using namespace std" not advisable?

    Because it dumps a lot of common class names and common function names into the global namespace, which may cause ambiguity.

    Code:
    #include <algorithm>
    using namespace std;
    
    namespace my
    {
      template <typename T>
        void
        sort( fancy_container<T>::iterator begin, fancy_container<T>::iterator end );
    }
    
    sort( b, e );
    Which sort is the one that should be called here? The standard one, or the one that is specialized for fancy_containers? The argument types are identical. I don't find a bunch of "using std::this" or "using std::that" at the beginning of a file much better though. I wrote a different main.
    Last edited by whiteflags; 05-19-2008 at 11:23 PM. Reason: added example

  12. #12
    Registered User
    Join Date
    May 2008
    Posts
    18
    Quote Originally Posted by m37h0d View Post
    using a map<string,unsigned int> would be much simpler!
    Well, I don't know what map<string,unsigned int> is suppose to be. Plus, I prefer to work with the features that the book have taught me so far (they are the only one in C++ I know right now anyway >_<).

    @citizen: Thank you very much for the explanation. I can't say I completely understand, but now I at least have an idea of what's going on.
    Last edited by tiachopvutru; 05-19-2008 at 11:27 PM.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    using a map<string,unsigned int> would be much simpler!
    Yes, but not yet. std::map has not yet been introduced, so at this point it is a question of problem solving with algorithms and a vector instead of using a more specific container.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. programming exercise
    By mashour06 in forum C Programming
    Replies: 1
    Last Post: 06-01-2009, 06:22 AM
  2. Line of data input method
    By larry_2k4 in forum C Programming
    Replies: 2
    Last Post: 04-28-2009, 11:34 PM
  3. Can I get some idea for exercise?
    By Rokemet in forum C++ Programming
    Replies: 6
    Last Post: 11-22-2007, 09:10 AM
  4. Tutorial review
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 03-22-2004, 09:40 PM
  5. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM