Q: C++ - Reversing a string (sentence and word) using a class - c++

For my code, I am trying to create a class with two functions that:
Display a cstring where each word is reversed
Display an entire cstring reversed
My two test sentences are "Hi There" and "To Be", so the output is:
erehT iH
eB oT
iH erehT
oT eB
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
class cStringType {
public:
char sentenceInput[80]; //Member variable
void reverse_sentence(); //Member function
void reverse_words(); //Member function
}; //Bottom of cStringType
int main()
{
cStringType sentence1, sentence2;
//Objects declared of cStringType
cout << "Please enter a sentence!\n" << endl;
cin.get(sentence1.sentenceInput, 79, '\n');
cin.ignore(80, '\n');
cout << "\nPlease enter another sentence!\n" << endl;
cin.get(sentence2.sentenceInput, 79, '\n');
cout << "\nThe first sentence reversed: ";
sentence1.reverse_sentence();
cout << endl;
cout << "The second sentence where each word is reversed: ";
sentence2.reverse_words();
cout << endl;
cout << endl;
cout << "The first sentence where each word is reversed: ";
sentence1.reverse_words();
cout << endl;
cout << "The second sentence reversed: ";
sentence2.reverse_sentence();
cout << endl;
return 0;
}
void cStringType::reverse_sentence()
{
char reverse_sentence;
//Reverse entire sentence using loop
for (int i = 0; i < strlen(sentenceInput) / 2; i++)
{
//Reverse the sentence using the length of the
//variable in the class
reverse_sentence = sentenceInput[i];
//First get the user input
//Set your variable equal to the variable in the class
sentenceInput[i] = sentenceInput[strlen(sentenceInput) - i - 1];
//Then reverse the characters and word order
//Starts from the last character in the array
//and goes backwards to 0
sentenceInput[strlen(sentenceInput) - i - 1] = reverse_sentence;
//Set the variable equal to the result
//sentenceInput is now the reverse of the user input in main
}
cout << sentenceInput << endl;
//Output of the new sentence
}
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
for (beginning = j, end = i - 1;
beginning < (i + j) / 2; beginning++, end--)
//j is the beginning of the array; increases
//i is the end of the array; decreases
{
reverse_words = sentenceInput[beginning];
//Set a variable equal to the first
//word in the original user input
sentenceInput[beginning] = sentenceInput[end];
//Set the first letter of a word equal to
//the last letter of a word
sentenceInput[end] = reverse_words;
//Set the result equal to the variable
//sentenceInput is now the user input where each
//word is reversed
}
}
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}
When I try to run the code, the output becomes something like this:
Please enter a sentence!
Hi There
Please enter another sentence!
To Be
The first sentence reversed: erehT iH
The second sentence where each word is reversed: oT eB
The first sentence where each word is reversed: There Hi
The second sentence reversed: Be To
I tried fixing it, but to no avail. The output is never correct.
Is there some way to fix this issue? Or better yet, to simplify the code? I believe the issue is with the code in the function.

The main problem with your code is that it's using the same buffer for both transformations. In other words: you are reversing the words in the same string which you've already reversed entirely. So you need to have another copy of the original string to do these independently.
Regarding simplifying your code you need to define a function that would reverse a string given a pointer and size or begin and end pointers. Then you can use this function on your entire string or on every word you find while searching for a space character:
char *begin = sentenceInput; //points to the beginning of the word
char *end = sentenceInput + strlen(sentenceInput);
for (char *it = begin; it != end; ++it)
if (*it == ' ') {
reverse(begin, it);
begin = it + 1;
}
reverse(begin, end); //reverse the last word
The reverse function can be either std::reverse, which can be used in the above code and on the entire string as follows:
std::reverse(sentenceInput, sentenceInput + strlen(sentenceInput))
or you can create a similar function like this:
void reverse(char *begin, char *end)
{
--end; //point to the last character instead of one-past-last
while (begin < end)
std::swap(*begin++, *end--);
}

I would suggest using stack for it, it is a natural way of looking at it.
so
#include <stack>
and then the function would be like that
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
stack<char> lastWord;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
//we want to print the last word that was parsed
while(!lastWord.empty())
{
//we print in the reverse order the word by taking off the stack char by char
cout<< lastWord.top();
lastWord.pop();
}
cout<<" ";
}
//if the letter is not space or end of string then push it on the stack
else
lastWord.push(sentenceInput[i]);
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}

Related

C++ Need some advices with Pig Latin string

I need to write a sentence in Pig Latin form and I am almost done it successfuly except for 1 case and I almost give up
for example :
If my word starts at a\e\o\u\i the word will look like easy -> easyway , apple -> appleway
and if it doesnt start with a letter that I wrote above
it will look like that: box -> oxbay , king -> ingkay
I succeed with the bolded part but in the first part with a\e\o\u\i letter at the beginning , I dont know where to put the w before and need some help with it
This is my code , thanks in advance
#include <iostream>
//Since those are used in ALL function of program, it wont hurt to set it to global
//Else it is considered EVIL to declare global variables
const int maxLine = 100;
char phraseLine[maxLine] = { '\0' };
void pigLatinString();
using namespace std;
void main()
{
// Displayed heading of program
cout << "* You will be prompted to enter a string of *" << endl;
cout << "* words. The string will be converted into *" << endl;
cout << "* Pig Latin and the results displayed. *" << endl;
cout << "* Enter as many strings as you would like. *" << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
cout << endl;
// This is the main loop. Continue executing until the user hits 'enter' to quit.
while (phraseLine[0] != '\0')
{
// Display the word (s) entered by the user
cout << "You entered the following: " << phraseLine << endl;
// Display the word (s) in Pig Latin
cout << "The same phrase in Pig latin is: ";
pigLatinString();
cout << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
}
return;
}
void pigLatinString() //phraseLine is a cstring for the word, maxline is max length of line
{ //variable declarations
char tempConsonant[10];
tempConsonant[0] = '\0';
int numberOfConsonants = 0;
char previousCharacter = ' ';
char currentCharacter = ' ';
bool isInWord = 0;
// for loop checking each index to the end of whatever is typed in
for (int i = 0; i < maxLine; i++)
{
//checking for the end of the phraseline
if (phraseLine[i] == '\0')
{//checking to see if it's in the word
if (isInWord)
{//checking to see that there wasn't a space ahead of the word and then sending the cstring + ay to the console
if (previousCharacter != ' ')
cout << tempConsonant << "ay" << endl;
}
return;
}
// this covers the end of the word condition
if (isInWord)
{// covers the condition of index [i] being the space at the end of the word
if (phraseLine[i] == ' ')
{
// spits out pig latin word, gets you out of the word, flushes the temp consonants array and resets the # of consonants to 0
cout << tempConsonant << "ay";
isInWord = 0;
tempConsonant[0] = '\0';
numberOfConsonants = 0;
}
cout << phraseLine[i] ;
}
else
{//this covers for the first vowel that makes the switch
if (phraseLine[i] != ' ')
{// sets the c string to what is in the phraseline at the time and makes it capitalized
char currentCharacter = phraseLine[i];
currentCharacter = toupper(currentCharacter);
// this takes care of the condition that currentCharacter is not a vowel
if ((currentCharacter != 'A') && (currentCharacter != 'E') &&
(currentCharacter != 'I') && (currentCharacter != 'O') && (currentCharacter != 'U'))
//this sets the array to temporarily hold the consonants for display before the 'ay'
{//this sets the null operator at the end of the c string and looks for the next consonant
tempConsonant[numberOfConsonants] = phraseLine[i];
tempConsonant[numberOfConsonants + 1] = '\0';
numberOfConsonants++;
}
else
{// this sets the boolean isInWord to true and displays the phraseline
isInWord = 1;
cout << phraseLine[i];
}
}
else
{
cout << phraseLine[i] ;
}
}
previousCharacter = phraseLine[i];
}
return;
}
You have two conditions to consider. if your word starts with a vowel, just add "way" to the end of the word, else move the first letter and add "ay" to the end.
This is a task that can be made a lot simpler by using std::string instead of C-strings. This is because you are now no longer concerned with exceeding your length or losing the null character. It also allows easier access to the Standard Library algorithms.
#include <algorithm>
#include <iostream>
#include <string>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiou");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::cout << make_pig_latin("apple") << '\n'
<< make_pig_latin("box") << '\n'
<< make_pig_latin("king") << '\n'
<< make_pig_latin("easy") << '\n';
}
The function above highlights how you can go about structuring your conversion. You just need to know if your word starts with a vowel or not, and take the appropriate action.
Output:
appleway
oxbay
ingkay
easyway
I did not get the impression that you have to care about words like 'phone'.
Looking through your code, you should try to do a better job at separating your concerns. Pig Latin is easier done one word at a time, but you have string splitting code and a lot of "not Pig Latin" code in your Pig Latin function. Your main can handle getting input. You should probably have a separate function to break the line up into individual words, using std::vector to hold the words would be best since it can grow on demand and doesn't have to know a specific capacity up front. You then iterate through your array of words and translate them individually. Depending on what your actual requirements are, it's possible that you don't even have to store the translated words, just print them directly to the screen.
Here's the same program, but now it can separate words. Note how the pig latin function doesn't have to change (much, I added upper-case vowels just because I didn't want to bothered converting words) in order for the added functionality to be added.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiouAEIOU");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::string phrase(
"A sentence where I say words like apple box easy king and ignore "
"punctuation");
std::istringstream sin(phrase);
std::vector<std::string> words(std::istream_iterator<std::string>(sin), {});
for (auto i : words) {
std::cout << make_pig_latin(i) << ' ';
}
}
Output:
Away entencesay hereway Iway aysay ordsway ikelay appleway oxbay easyway ingkay andway ignoreway unctuationpay

Palindromes in C++

I'm trying to make a program that uses stacks (w pop, push, etc.) to read in a text file with lots of sentences that are taken one at a time and outputs whether each line is a palindrome or not (words that are spelled the same forwards and backwards). I believe its very close to being a completed program, but it only returns false even when the string is a palindrome. I want it to return true when the string is in fact a palindrome.
EDIT: Tried a new method with three stacks instead. Still getting a false return from bool tf every time.
int main() {
Stack s(100); // Initialize two different stacks
Stack q(100);
Stack temp(100);
string line; // String to hold each individual line of the file
char letter;
char x; // For comparisons
char y;
// open the file
ifstream input;
input.open(READFILE);
// Check that it is open/readable
if (input.fail()) {
cout << endl << "Sorry, file not available, exiting program. Press enter";
cout << endl;
cin.get(); // Grab the enter
return 0;
}
while (getline(input, line)) { // Read the file line-by-line into "line"
cout << "The line: " << line << endl;
int length = line.length(); // Sets length equal to string length
for (int i =0; i<length; i++){ // Capitalizes string
line[i] = toupper(line[i]);
}
for (int i = 0; i < length; i++) { // Loop through for every letter in the line
if (line[i] == ' ' ) {
line.erase(i,1); // Takes spaces out of the line
length--;
}
if (ispunct(line[i])){
length--;
}
if (!ispunct(line[i])){ // Removes punctuation
letter = line[i]; // Push each letter onto the stack
s.push(letter);
}
}
for (int i = 0; i < length; i++) { // Popping half the letters off of the s stack
s.pop(letter); // and pushing them onto the q stack
q.push(letter);
temp.push(letter);
}
for (int i = 0; i < length; i++) {
temp.pop(letter);
s.push(letter);
}
bool tf = true; // Pop off the top of each stack and compare
while (!s.empty()) { // them to check for a palindrome
s.pop(x);
q.pop(y);
if (x == y);
else tf = false;
}
if (tf){
cout << "is a palindrome!" << endl;
}
if (!tf) {
cout << "is NOT a palindrome" << endl;
}
}
}
for (int i = 0; i < length/2; i++) // Popping half the letters off
//of the s stack
q.push(letter); // and pushing them onto the q
//stack
}
Here you're pushing the same letter over and over again.
Even if you rewrite as the comment states it will be wrong.
if you pop half of ABBA you have BA and AB and compare B=A
you need to rethink your strategy. Maybe push half of the string to s then loop backwards from length and push to q
Like someone else mentioned, even after fixing the for loop with the "q" stack, the general strategy is not correct. In fact you don't need two stacks. (or even one stack, but you can use a stack if desired.)
You do have the right idea in comparing the back half of the letters with the front half. In general, to find a palindrome you just need to see if the string is equal to the reversed string or that the first half is equal to the back half.
You can use a stack to store the string in reverse. All you need is the stack and the string. However, there is the extra problem here in that the lines of strings contain spaces and punctuation that you want to ignore. Using the erase() method reduces the length of the string as you go, so you need a temporary variable to rebuild the formatted string at the same time as the stack. EDIT: I saw your update to accounting for the reduced length; that's great -- it can save even the use of a temp variable to hold the formatted string so that the variable string line is all that is needed.
Here is another version of your while loop that uses one stack and a temp string variable. It uses half the formatted string to compare against the top of the stack (which represents the "back" of the string).
string cleanString;
//cout << "test3";
while (getline(input, line)) { // Read the file line-
//by-line into "line"
cout << "The line read was: " << line << endl;
int length = line.length(); // Sets length equal to
//string length
for (int i =0; i<length; i++) // Capitalizes string
line[i] = toupper(line[i]);
for (int i = 0; i < length; i++) // Loop through for //every letter in the line
if ( !(line[i] == ' ' || ispunct(line[i]))) { // Ignore space & punctuation
letter = line[i]; // Push each letter onto
s.push(letter); //the stack
cleanString.push_back(letter); //and to the "cleaned" string to compare with later
//cout << cleanString << endl; //test
}
length = cleanString.length();
bool tf = true;
for (int i = 0; i < length/2; i++) { // Pop off the top of stack
s.pop(x); // to compare with front of string
if ( cleanString[i] != x ) { //not a palindrome
tf = false;
break;
}
}
if (tf){
cout << "is a palindrome!" << endl;
}
if (!tf) {
cout << "is NOT a palindrome" << endl;
}
}
But it's simpler to skip the use of the stack altogether and instead just use the temp "cleaned" string, checking for a palindrome in a for loop with two counters: one for the the front and one for the back.
So after the capitalization:
// Instead of a stack, just build a string of chars to check for a palindrome
for (int i = 0; i < length; i++)
if ( !(line[i] == ' ' || ispunct(line[i]))) {
letter = line[i]; // Push each letter onto
cleanString.push_back(letter); // a temp string
}
length = cleanString.length(); //use length of formatted string
bool tf = true;
int front = 0; // first char of string
int back = length-1; // last char of string
for (; i < length/2; front++, back--)
if ( cleanString[front] != cleanString[back] ) { //not a palindrome
tf = false;
break;
}
Another option is to use the inbuilt reverse() function in the <algorithm> header file after building the temp string:
#include <algorithm> // reverse()
string cleanString;
string reversedCleanString;
//...
// Instead of a stack, just build a string of chars to check for a palindrome
for (int i = 0; i < length; i++)
if ( !(line[i] == ' ' || ispunct(line[i])))
cleanString.push_back(line[i]);
reversedCleanString = cleanString; // store copy of string to reverse
reverse(reversedCleanString.begin(), reversedCleanString.end() ); // reverse
bool tf = true;
if ( cleanString != reversedCleanString)
tf = false;
// ...
As moooeeep mentioned the comments, using std::string's reverse iterators simplifies this even further after the capitalization:
string cleanString;
//...
// Format line to test if palindrome
for (int i = 0; i < length; i++)
if ( !(line[i] == ' ' || ispunct(line[i])))
cleanString.push_back( line[i] );
bool tf = true;
if ( cleanString != string(cleanString.rbegin(), cleanString.rend() )
tf = false;
// ...
Also, like moooeeeep mentioned, encapsulating the different parts of the while loop into their own separate functions is a good idea to make not just debugging easier but also understanding the logical flow of the problem more intuitively.
For example the while loop could look like this:
while (getline(input, line)) { // Read the file line-by-line into "line"
//echo input
cout << "The line read was: " << line << endl;
// validate/format the line
extractChars( line ); //remove space/punctuation
capitalizeString( line ); // capitalize chars for uniformity
//check if formatted line is a palindrome and output result
if ( is_palindrome( line ) )
cout << "Line IS a palindrome << endl;
else
cout << "Line IS NOT a palindrome << endl;
}

Why am I missing a value when I run this loop to print each word in a string?

I am attempting to write a program that will accept an input from the user and then print each one of the words in the sentence on a separate line. The code below works except it is missing the last word in any sentence that is input. I did not include the header in this snippet. Can anyone tell me why this is?
int main()
{
//Declare variables
string userSentence = " ";
string permanantUserSentence = " ";
int spaceNumber = 0;
int wordNumber = 0;
int characterCount = 0;
int reverseCount = 0;
int posLastSpace = -1;
int posSpace = 0;
//Begin the loop
while(userSentence != "quit" && userSentence != "q")
{
//Prompt the user for their sentence
cout << "Enter command: ";
getline(cin, userSentence);
permanantUserSentence = userSentence;
//Condition to make sure values are not calculated and printed for the quit conditions
if(userSentence != "quit" && userSentence != "q")
{
//Print each word in the string separately by finding where the spaces are
int posLastSpace = -1;
int posSpace = userSentence.find(" ", posLastSpace + 1);
while(posSpace != -1)
{
cout << "expression is: " << userSentence.substr( posLastSpace+ 1, posSpace - posLastSpace - 1) << endl;
posLastSpace = posSpace;
//Find the next space
posSpace = userSentence.find(" ", posLastSpace + 1);
}
//Clear the input buffer and start a new line before the next iteration
cout << endl;
}
}
}
You are not printing the remainder of your input when you exit your while loop.
The end of the sentence generally won't have any spaces after it. So your while loop exits with some remainder (the last word and whatever follows). Therefore, you need to print the remainder of your input out to print out the word.

How to search array of strings in C++

I want to be able to search an array of strings in C++. I have this data:
"Foo Becky, 924-334-2514",
"Becky Warren, 555-1223",
"Geri Palmer, 555-8787",
"Ron Palmer, 555-2783"
If the user types Bec, the program finds the name Foo Becky, 924-234-2314. If the user types Palmer, then the program should show Geri Palmer, 555-8787 and Ron Palmer, 555-2783
Here is what I have so far:
#include <iostream>
#include <string>
using namespace std;
int main(){
int n;
string search;
while(1){
cout << "How many data you want to input: "<< endl;
cin >> n;
cin.ignore(1000, 10);
if(n > 0 && n < 20){
break;
}
cout << "Number of data can not be negative or more than 20. "<< endl;
}
string* data = new string[n];
for(int i=0; i< n; i++){
cout << "Enter [First Name] [Last Name], [Phone-Number] and then hit "
<< "enter." << endl << "e.g: Foo Becky, 925-245-413"<< endl;
getline(cin,data[i]);
cout << endl;
}
cout << "Enter what you want to search for: "<< endl;
getline(cin, search);
for(int i =0; i< n; i++){
if(search == data[i]){
cout << data[i]<< endl;
}
}
delete [] data;
return 0;
}
How do I search an array of strings in C++?
You have to use the find method of std::string. This function return the start postion of string searched for in the string searched in. If no match was found it returns npos witch is actually just -1.
if(data[i].find(search, 0) != std::string::npos);
{
cout << data[i]<< endl;
}
You should use find, as A4L already mentioned. I just want to add that your use of cin.ignore will not work well if bad value entered. you need
cin.clear()
also. see this link for more details.
How to search an array of strings example in C++:
This is the brute force search method. Brute force means means we step through the entire string array and at each index of the array we search for our matching string.
#include<iostream>
#include<string>
using namespace std;
int main(){
//Create a structure to hold the data:
string data[] = {"pidgeon", "abcd", "1234", "%^*#"};
//Get the length of the array.
int size = 4;
//loop through all the items and print them if they match
string matchString = "bc";
for(int x = 0; x < size; x++){
if (data[x].find(matchString, 0) != std::string::npos){
cout << data[x] << endl;
}
}
}
Above code prints:
abcd
You should be verbalizing the above code from top to bottom in your head like this:
An array of string called data is initialized to contain 4 elements and given four values pidgeon, abcd, 1234 and %^&#. An int variable called size is created which represents the number of elements in the string array. A string variable called matchString is created which contains the string 'bc'.
The for loop index starts at position zero and increments by 1 until it reaches one less than the size of the array. So the for loop goes through: 0, 1, 2, 3. The first value of x is 0. The if statement resolves data[0] to be pidgeon. The find method is applied against that string and two parameters are passed in. The string to be matched, and the position of the first character in the string to be considered in the search (0).
if 'bc' exists within 'pidgeon' then it will return the position of the first character of the first match, otherwise it will print std::string:npos which is the maximum value for size_t designating not found.
bc does not exist in pidgeon so it skips the interior of the for loop. The for loop continues to index position 1. bc is contained in abcd. So that string is printed. When all the items are searched, the for loop ends and the program completes.

C++ Identifying the Frequency of words occurring in a sentence

What is the best STL to use for this task? I've been using Map,
and I couldn't get it to work. I'm not sure how I am supposed to check the number of same words that occur in the sentence for example:
I love him, I love her, he love her.
So I want the program to prompt the user to enter an integer, lets say i enter 3, the output will be love as the same word occurs 3 times in the sentence. But what method to use if I want to do a program like this?
Currently my program prompts for the user to enter the word, and then it shall return how many time that word occurs, which for word love, is 3. but now i want it the other way round. Can it be done? Using which STL will be better?
I assume you use a map to store the number of occurrences.
Well,you first have to understand this,since you are using a map,the key is unique while the stored data may not be unique.
Consider a map, x
with contents
x["I"]=3
x["Love"]=3
x["C"]=5
There is unique a mapping from the key to the value,and not the other way round,if you want this one to one mapping ,i would suggest a different data structure.If you want to use map,and still search for an element,using STL search function or your own.Or you can write your search function.
search().
map<string,int>::iterator ser;
cin>>check;
for(ser=x.begin();ser!=x.end();++ser)
{
if(ser->second==check)
{
cout<<"Word"<<ser->first<<endl;
break;
}
}
First build the mapping from word to count and then build the reverse multi-mapping from that. Finally, you can determine which words occur with a given frequency:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
int main()
{
std::string str("I love him, I love her, he love her");
std::istringstream ss(str);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::map<std::string, int> word_count;
std::for_each(begin, end, [&](const std::string& s)
{
++word_count[s];
});
std::multimap<int, std::string> count_words;
std::for_each(word_count.begin(), word_count.end(),
[&](const std::pair<std::string, int>& p)
{
count_words.insert(std::make_pair(p.second, p.first));
});
auto its = count_words.equal_range(3);
std::for_each(its.first, its.second,
[](const std::pair<int, std::string>& p)
{
std::cout << p.second << std::endl;
});
}
/******************************************************************
Name : Paul Rodgers
Source : HW1.CPP
Compiler : Visual C++ .NET
Action : Program will read in from standard input and determine the
frequency of word lengths found in input. An appropriate
table is also displayed. Maximum word length is 15 characters
words greater then 15 are counted as length 15.
Average word length also displayed.
Note : Words include hyphenated and ones with apostrophes. Words with
apostrophes, i.e. Jim's, will count the apostrophe as part of the
word length. Hyphen is counted if word on same line, else not.
Also an int array is used to hold the number of words with
length associated with matching subscript, with subscript 0
not being used. So subscript 1 corresponds to word length of 1,
subscript 2 to word length of 2 and so on.
------------------------------------------------------------------------*/
#include <iostream>
#include <ctype.h>
#include <iomanip>
using namespace std;
int NextWordLength(void); // function prototypes
void DisplayFrequencyTable(const int Words[]);
const int WORD_LENGTH = 16; // global constant for array
void main()
{
int WordLength; // actual length of word 0 to X
int NumOfWords[WORD_LENGTH] = {0}; // array holds # of lengths of words
WordLength = NextWordLength();
while (WordLength) // continue to loop until no word, i.e. 0
{ // increment length counter
(WordLength <= 14) ? (++NumOfWords[WordLength]) : (++NumOfWords[15]);
WordLength = NextWordLength();
}
DisplayFrequencyTable(NumOfWords);
}
/********************** NextWordLength ********************************
Action : Will determine the length of the next word. Hyphenated words and
words with apostrophes are counted as one word accordingly
Parameters : none
Returns : the length of word, 0 if none, i.e. end of file
-----------------------------------------------------------------------*/
int NextWordLength(void)
{
char Ch;
int EndOfWord = 0, //tells when we have read in one word
LengthOfWord = 0;
Ch = cin.get(); // get first character
while (!cin.eof() && !EndOfWord)
{
while (isspace(Ch) || ispunct(Ch)) // Skips leading white spaces
Ch = cin.get(); // and leading punctation marks
if (isalnum(Ch)) // if character is a letter or number
++LengthOfWord; // then increment word length
Ch = cin.get(); // get next character
if ((Ch == '-') && (cin.peek() == '\n')) //check for hyphenated word over two lines
{
Ch = cin.get(); // don't count hyphen and remove the newline char
Ch = cin.get(); // get next character then on next line
}
if ((Ch == '-') && (isalpha(cin.peek()))) //check for hyphenated word in one line
{
++LengthOfWord; // count the hyphen as part of word
Ch = cin.get(); // get next character
}
if ((Ch == '\'') && (isalpha(cin.peek()))) // check for apostrophe in word
{
++LengthOfWord; // count apostrophe in word length
Ch = cin.get(); // and get next letter
}
if (isspace(Ch) || ispunct(Ch) || cin.eof()) // is it end of word
EndOfWord++;
}
return LengthOfWord;
}
/*********************** DisplayFrequencyTable **************************
Action : Will display the frequency of length of words along with the
average word length
Parameters
IN : Pointer to array holding the frequency of the lengths
Returns : Nothing
Precondition: for loop does not go beyond WORD_LENGTH
------------------------------------------------------------------------*/
void DisplayFrequencyTable(const int Words[])
{
int TotalWords = 0, TotalLength = 0;
cout << "\nWord Length Frequency\n";
cout << "------------ ----------\n";
for (int i = 1; i <= WORD_LENGTH-1; i++)
{
cout << setw(4) << i << setw(18) << Words[i] << endl;
TotalLength += (i*Words[i]);
TotalWords += Words[i];
}
cout << "\nAverage word length is ";
if (TotalLength)
cout << float(TotalLength)/TotalWords << endl;
else
cout << 0 << endl;
}
#include<iostream>
#include<string>
#include<vector>
#include<cstddef>
#include<map>
using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::vector;
using std::map;
int main() {
cout << "Please enter a string: " << endl;
string str;
getline(cin, str, '\n');
size_t str_len = str.size();
cout << endl << endl;
size_t i = 0, j = 0;
bool pop = false;
map<string, int> myMap;
for (size_t k = 0; k < str_len-1; k++) {
if (((k == 0) && isalpha(str[0])) || (!(isalpha(str[k-1])) && isalpha(str[k])))
i = k;
if ( isalpha(str[k]) && !(isalpha(str[k+1])) ) {
j = k;
pop = true;
}
if ( (k == str_len-2) && isalpha(str[k+1]) ) {
j = k+1;
pop = true;
}
if ( (i <= j) && pop ) {
string tmp = str.substr(i, j-i+1);
cout << tmp << '\t';
myMap[tmp]++;
pop = false;
}
}
cout << endl << endl;
map<string, int>::iterator itr, end = myMap.end();
for (itr = myMap.begin(); itr != end; itr++)
cout << itr->first << "\t - - - - - \t" << itr->second << endl;
cout << endl;
return 0;
}