I'm having trouble with this project because when I put a sentence such as "cat is not a dog", it will not say "Didn't find repeated word" as intended. Instead, it will say "Found repeated word", as if I it was true. Also, each time it is run for the first time, the first letter is removed from the user input. Why?
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <time.h>
#include <stdio.h>
using namespace std;
int main()
{
int count = 0;
bool repeat = false;
char yn;
string input, newWord, firstword;
do
{
count = 0;
repeat = false;
cin.sync();
cout << "Please enter a sentence: ";
cin.ignore();
getline(cin, input);
while (input.at(count) != ' ')
count ;
firstword = input.substr(0, count);
input = input.substr(count );
count = 0;
while(count < input.size() && repeat == false)
{
count ;
while (count < input.size() && input.at(count) != ' ')
count ;
newWord = input.substr(0, count);
if (firstword.compare(newWord) == 0)
input = input.substr(count );
else
repeat = true;
}
if (repeat == true)
{
cout << "\nI found a repeated word!";
cout << "\nWould you like to try again? (y/n)";
cin >> yn;
}
else if(repeat == false)
{
cout << "\nI didn't find a repeated word.";
cout << "\nWould you like to try again? (y/n)";
cin >> yn;
}
} while (yn == 'y');
}
CodePudding user response:
You program only checks if the first word is repeated annywhere else in the sentence...
Looking for a repeated word being: Each word must be checked against its immediate predecessor.
You're almost there. You forgot to reassign firstWord to newWord at te end of the parsing loop.
while(count < input.size() && repeat == false)
{
// ...
newWord = input.substr(0, count);
if (firstword.compare(newWord) == 0)
input = input.substr(count );
else
repeat = true;
firstWord = newWord; // <-- Assign here.
}
Just an aside note, a trick of the trade, if you will.
if (repeat == true)
//...
else if(repeat == false) // <- Avoid doing that. Use plain else for booleans.
A bool
can only have two values. And this kind of else if
construct will bring unexpected surprises when plain int
s are used for boolean equations. (if repeat was 3, which path does each cases of 0, 1, 3 follow?)
Have you tried removing the call to std::cin.sync()
?
CodePudding user response:
Print your input after getline to be sure it's correctly saved. You probably don't need cin.ignore();. The first character is not saved.
An alternative sollution would be to use the following:
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <sstream>
using namespace std;
int main()
{
int pos = 0;
string input;
cout << "Please enter a sentence: ";
getline(cin, input);
map<string, int> count_words;
stringstream ss(input);
string word;
while(getline(ss, word, ' '))
count_words[word] ;
map<string, int>::const_iterator it;
for(it = count_words.begin() ; it != count_words.end() ; it)
if( it->second == 2)
cout << "Found duplicate: " << it->first << endl;
return 0;
}
this answer(https://stackoverflow.com/a/236803/4388908) provides a good method to split your input.
The rest: Programming Pearls by Jon Bentley