# C++ Notes: Examples: Compress words

## Problem

Read a sequence of words, eliminate all vowels ("aeiou", lower case only). If the resulting word has two or fewer characters, don't eliminate any vowels. Sort and print the words.

The modification of each word should be made by calling a void function, compressWord, where the word is the single parameter. This function must be defined in a separate file.

### Example

Input

          This is the test data for a
          first run.

Output

          Ths
          a
          dt
          fr
          frst
          is
          rn.
          th
          tst

### Suggestions

- vector. There is no bound on the number of words, so use an appropriate data structure. I recommend `vector`. I you're not familiar with it, you can find a short description starting on p 102 of the textbook.
- string. Another STL class that will be useful is string. There is a little information in the textbook about it. Some additional features you could use are (assuming `string s = "abcdef";`).
  - You can use the subscription operator to access individual characters. `s[4]` is 'e'.
  - You can delete substrings using erase. For example, after `s.erase(4, 1)`, the value in s is "abcdf".
  You can find additional string notes at ANSI String Class.
- cin, cout. Use the standard IO streams for the input and output. cin works nicely with strings to read "words", strings of non-whitespace characters. Don't worry about real text problems like case and the fact that punctuation will be included in the words.
- sort. You don't have to write your own sort; in fact it's a bad idea to do so (bugs, inefficiency). Use the STL sort function. For example.

          vector<string> words;
          . . .
          sort(words.begin(), words.end());

- Iterative programming. Use iterative programming. Start with a very small program (main that does nothing), test it, add a feature, test it, and continue making small additions and testing. This style is usually effective in making your programming go faster with fewer bugs.

## A solution

There are many possible ways to solve this problem. Here is one.

### The header file - `compress.h`

      1
      2
      3
      4
    // readModSortWrite/compress.h
    // Fred Swartz - 2004-11-20

    void compress(string& w);

### The main program - `readModSortWrite.cpp`

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
    // stl-vector-mod-sort/readModSortWrite.cpp -- Read, compress, sort words.
    // Fred Swartz - 2004-11-07

    // This program is intended as an exercise in using
    //     vector, string, multiple source files, sort.
    // It reads words, removes vowels (see rules in compress.cpp),
    //     sorts, and prints them.

    #include <iostream>
    #include <stdlib.h>
    #include <vector>
    #include <algorithm>
    using namespace std;

    #include "compress.h"

    //========================================================== main
    int main() {
        string word;           // Used to save input word.
        vector<string> words;  // Save words here.

        //... Read, compress, and save words until EOF
        while (cin >> word) {
            compress(word);
            words.push_back(word);
        }

        //... Use STL sort to put them in alphabetical order.
        sort(words.begin(), words.end());

        //... Print the compressed, sorted words.
        for (int i=0; i<words.size(); i++) {
            cout << words[i] << endl;
        }

        system("PAUSE");  // Keep Dev-C++ window open
        return 0;
    }

### The compress function - `compress.cpp`

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
    // readModSortWrite/compress.cpp - Read words, compress, sort, print.
    // Fred Swartz - 2004-11-20

    //  The compress() function removes vowels from its parameter.
    //  1. If result would be shorter than two chars, it is unchanged.
    //  2. Only lowercase characters are removed.

    #include <string>
    using namespace std;

    #include "compress.h"

    const char VOWELS[] = "aeiou";
    const int VMAX = 5;

    //========================================================= compress
    void compress(string& w) {
        string temp = w;    // Save the original parameter.

        //... Don't change words that are already short.
        if (w.size() <= 2) {
            return;  // No need to even look if it's this short.
        }

        //... Iterate character-by-character over each string.
        for (int i=w.size()-1; i >= 0; i--) {
            //... Iterate over each of the vowel characters.
            for (int v=0; v<VMAX; v++) {
                if (w[i] == VOWELS[v]) {  // When it's a vowel
                    w.erase(i, 1);        // Remove it.
                    break;                // Try next word character.
                }
            }
        }

        //... If the result has fewer than two characters, use original.
        if (w.size() < 2) {
            w = temp;
        }
    }