// ---------------------------------------------------------------- // System Headers // ---------------------------------------------------------------- #include #include #include #include #include // ---------------------------------------------------------------- // Using directives // ---------------------------------------------------------------- using std::string; using std::vector; // ---------------------------------------------------------------- // isVowel - Return true if 'c' is a vowel, false otherwise // ---------------------------------------------------------------- static bool isVowel(char c, int index) { static const string vowels("aAeEiIoOuU"); return( vowels.find(c) != string::npos || (index > 0 && (c == 'y' || c == 'Y')) ); } // ---------------------------------------------------------------- // isSeparator - Return true if 'c' is a separator, false otherwise // ---------------------------------------------------------------- static bool isSeparator(char c) { return(isspace(c) || c == ',' || c == '?' || c == '.' || c == '!'); } // ---------------------------------------------------------------- // tokenize - Return 's' as a vector of strings, tokenized using // the 'isSeparator' function above // ---------------------------------------------------------------- static vector tokenize(const string &s) { vector tokens; string current; for(int i = 0, n = s.size(); i < n; i ++) { current += s[i]; if(i + 1 == n || isSeparator(s[i]) != isSeparator(s[i + 1])) { tokens.push_back(current); current = ""; } } return(tokens); } // ---------------------------------------------------------------- // toLower - Convert 'theString' to lower case // ---------------------------------------------------------------- static string toLower(string theString) { string output; for(char c : theString) output += (char)tolower(c); return(output); } // ---------------------------------------------------------------- // gSpeak - Convert 'theString' to g-speak // ---------------------------------------------------------------- static string gSpeak(const string &theString) { string output; for(string token : tokenize(theString)) { if(isSeparator(token[0])) { output += token; } else { string result; string current; int count = 0; for(int i = 0, n = token.size(); i < n; i ++) { if(!isVowel(token[i], i)) { result += token[i]; } else { current += token[i]; bool last = (i + 1 == n); if(last || !isVowel(token[i + 1], i + 1)) { result += current; // ------------------------------------------ // If 'current' is 'e' or 'E' we will // only apply the 'g effect' if we have // not seen a previous run of vowels // (i.e. count == 0) // // So we will apply the g effect // to the 'e' in words like: // 'the' and 'me' but not to words // like: 'plate' and 'sure' // ------------------------------------------ if(toLower(current) != "e" || !last || count == 0) result += "g" + toLower(current); current = ""; } count++; } } output += result; } } return(output); } // ---------------------------------------------------------------- // main // ---------------------------------------------------------------- int main() { static const string list[] = { "My name is Bond, James Bond", "We come in peace -- shoot to kill", "You can't always get what you want", "If you hear the people, you won't have to fear the people", "Are you sure you ate the plate?" }; for(string s : list) std::cout << "'" << s << "' => '" << gSpeak(s) << "'\n"; return(0); }