String with an interchangeable letter - c++

The directions for my assignment are as follows:
Return the number of times that the string "hope" appears anywhere in the given string, except we'll accept any letter for the 'p', so "hode" and "hooe" count.
I am struggling to figure out how to make the third letter equal anything and still have the program identify that it is correct.
My code so far is quite obviously wrong but ill include it nonetheless.
one big problem is i can't tell the array to check if it matches the string.
int wordsFunction(string words)
{
int num = 0;
for(int i = 0; i < words.length(); i++)
{
if(words[i] == "Hope" || words[i] == "hope")
{
num++;
}
}
return num;
}
main()
{
string words;
cout << "Enter a string: ";
getline(cin, words);
cout << wordsFunction(words);

My code so far is quite obviously wrong
That is true. I wouldn't explain why your code is wrong, and go straight to a description of a fix.
Your main reads the string that allows spaces, which is good: the I/O part of your code does not need to be changed.
Now observe that to detect the word "ho*e", with * denoting any single character, at a position i in a word w, you need to check that w[i] is an 'h', w[i+1] is an 'o', w[i+3] is an 'e', and that the index i+3 is valid. This becomes a simple check:
if (i+3 < w.size() && w[i] == 'h' && w[i+1] == 'o' && w[i+3] == 'e') {
count++;
}

Related

I need help in c++ change cases

#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence ="";
cin >> sentence; //aab
int i;
for (i=0;i=sentence.length();i++){
if (i<=65 && i>=90) {
sentence = sentence[i] + 32;
}
else if (i<=97 && i>=122){ //i=0,
sentence = sentence [i]-32;
}
}
cout << sentence;
return 0;
}
When I enter this code for changing cases of letters it keeps asking me to enter more although I have only one cin in the code why does that happen?
Problem one is inadvertent assignment. Look at your loop condition:
for (i=0;i=sentence.length();i++)
That assigns i rather than comparing it, resulting in an infinite loop. Use < instead of =:
for (i=0; i < sentence.length(); i++)
Problem two is you're comparing the position in the string to the character ranges rather than the character itself, and the comparison is backwards and can never be true:
if (i<=65 && i>=90)
Should be:
if (sentence[i] >= 65 && sentence[i] <= 90)
Same for the lower case range.
Finally, you don't want to change the whole sentence to one character, just that character:
sentence = sentence[i] + 32;
Should be:
sentence[i] = sentence[i] + 32;
Again, same for the lower case range.
With these changes, it seems to work, at least for single words. If you want to do entire sentences, I'd recommend using std::getline(std::cin, sentence); rather than cin >> sentence;.

Counting syllables in a word C++

I have created a program to count the syllables in a word inputted by the user. The user is to enter any amount of words followed by the enter key until the (#) key is entered, then the program is to display the words in a table followed by the syllable count for each word.
I am having issues with the "silent e" portion of my program.
if (word_length - 1 == 'e')
{
vowels = vowels - 1;
It seems as though it is not able to pick up the last letter in the string of words. I have tried to move some of the if statements around to see if that helps and to better identify where the problem lies, and from what I have noticed, as stated earlier i believe it to be with the silent e portion of the code.
It is difficult to find even the smallest errors in my code, so I am asking for another set of eyes to gaze over my code.
Any help will be greatly appreciated.
Also, I have yet to complete the formatting of my results table, so please over look that.
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
string word_1 = "create list";
int vowels = 0;
int word_length; // better to set .length() into variable to eliminate warnings
int words_to_print = 0; // this will count how many words to print to use in for loop later
/*
vector <variable type> name_of_vector[size of vector];
creating vectors
leaving them empty for now
*/
vector <string> words_saved;
vector <int> number_of_syllables_saved;
cout << "Enter 4 words from the English dictionary, to determine the amount of syllables each word has." << endl;
cout << "Please enter [#] when finished, to create a list." << endl;
cin >> word_1;
while (word_1 != "#") // as long as user doesnt enter # you can enter a word and
{ // have it run thru the syllable logic
word_length = word_1.length();
words_to_print++;
words_saved.push_back(word_1);
// ^ this saves the word into the next availabe index of vector for strings.
for (int i = 0; i < word_length ; i++) // length is a variable now instead of function syntax this
{ // eliminates the <: signed/usnsigned mismatch warning below
if ((word_1[i] == 'a') || (word_1[i] == 'e') || (word_1[i] == 'i') || (word_1[i] == 'o') || (word_1[i] == 'u') || (word_1[i] == 'y'))
{
vowels = vowels + 1;
if ((word_1[i + 1] == 'a') || (word_1[i + 1] == 'e') || (word_1[i + 1] == 'i') || (word_1[i + 1] == 'o') || (word_1[i + 1] == 'u') || (word_1[i + 1] == 'y'))
{
vowels = vowels - 1;
if (word_length - 1 == 'e')
{
vowels = vowels - 1;
if (vowels == 0)
{
vowels = vowels + 1;
}
}
}
}
}
number_of_syllables_saved.push_back(vowels);
//^ this puts number of syllables into vector of ints
vowels = 0; // this resets the amounts so it can count vowels of next word and not stack from previous word
cin >> word_1; // this will reset the word and controls loop to print out chart if # is entered
}
// use a for loop to print out all the words
cout << endl << endl << endl;
cout << "Word: " << setw(30) << "Syllables: " << endl;
for (int x = 0; x < words_to_print; x++)
{
cout << words_saved[x] << setw(20) << number_of_syllables_saved[x] << endl;
}
//system("pause");
return 0;
}
You are comparing the character 'e' to the integer word_length - 1 instead of comparing it to the last character of your string as you intended.
You should replace if (word_length - 1 == 'e') with if (word_1[word_length - 1] == 'e').
Your nested if-statements don't get evaluated at the anticipated index.
Say the input is "state".
At i = 0, word_1[i] = 's', doesn't pass the first if statement.
At i = 1, word_1[i] = 't', doesn't pass the first if statement.
At i = 2, word_1[i] = 'a', vowels becomes 1. The program does not proceed further down the nested if statements since word_1[i+1] is 't'.
At i = 3, word_1[i] = 't', doesn't pass the first if statement.
At i = 4, word_1[i] = 'e', vowels becomes 2. The program does not proceed further down the nested if statements since word_1[i+1] is garbage value.
As you can see, it never reaches the nested if-statements as you intended

C++ cin.ignore To ignore spaces, numbers, and characters to test a palindrome

I need to process a user input to see if it is a palindrome. Our professor said to use cin.ignore() to ignore spaces, numbers, and other characters so we will just compare the letter inputs.
So far I have just found code that ignores just one of these at a time and the code is more advanced than my learning so I do not know how to modify or apply it to my code.
I have the code to check the palindrome, I just do not know how to make it ignore the unwanted inputs.
Sorry this sort of question has been asked many times over but I cannot seem to figure it out.
Thanks in advance.
do
{
checkInput = false;
cout << "Enter the Palindrome: ";
getline(cin, input);
len = input.length();
if (len == 0)
{
cout << "\nNo data was entered, please enter a palindrome.\n";
checkInput = false;
}
} while (checkInput);
for (int i = 0, j = input.size() - 1; i < input.size(); i++, j--)
{
if (input[i] != input[j] && input[i] + 32 != input[j] && input[i] - 32 != input[j])
{
isPalindrome = false;
break;
}
}
if (isPalindrome)
{
cout << "This is a Palindrome!!" << endl;
}
else
{
cout << "This is not a Palindrome." << endl;
}
im assuming that input is a string. if so then what we want to do before your for loop is have another for loop to run through the string and remove anything unwanted from the string. I am going to assume that all you want to deal with are the upper and lowercase letters, as we are focusing on the ascii values between 65-90 and 97-122. source http://www.ascii-code.com/
to so do we can simply check each index in the string to see if it falls between these two ranges, and if it doesn't, then delete it.
for(unsigned int i = 0; i<input.size();i++)
{
if(input[i]< 65 || (90 <input[i] && input[i] < 97) || input[i] > 122)
{
input.erase(i,1);
i--
}
}
that should work.

How can I get a cin loop to stop upon the user hitting enter?

Here's my C++ code right now:
// Prompt user loop
char preInput;
do {
// Fill the vector with inputs
vector<int> userInputs;
cout << "Input a set of digits: " << endl;
while(cin>>preInput){
if(preInput == 'Q' || preInput == 'q') break;
int input = (int) preInput - '0';
userInputs.push_back(input);
}
// array of sums sync'd with line #
int sums[10] = {0};
// Calculate sums of occurance
for(vector<int>::iterator i = userInputs.begin(); i != userInputs.end(); i++){
int currInput = *i;
for(int numLine = 0; numLine < lines.size(); numLine++){
sums[numLine] += lineOccurances[numLine][currInput];
}
}
int lineWithMax = 0;
for(int i = 0; i < 10; i ++)
if(sums[i] > sums[lineWithMax]) lineWithMax = i;
cout << lines[lineWithMax] << endl;
// Clear vector
userInputs.clear();
} while (preInput != 'Q' && preInput != 'q')
Don't worry about the function of the loop, I just need it to run in a certain way.
If a user types in "123" the loop should load the chars 1,2,3 into userInputs as separate elements.
Upon hitting enter, the loop needs to execute all of the code below the while(cin>>preInput){} statement, clear the userInput vector, and repeat until the character Q is entered. This is not what's happening. The way the loop is currently written, The program takes user input until the user hits Q, enter essentially does nothing. I need the code to execute whenever the user hits enter. I've been playing with this for a while but I'm not too familiar with taking data through a char into a vector via cin so I'm not sure how to do this...Can anyone point me in the right direction?
Would changing the cin>>preInput to a getline work? Or would this attempt to put the value say..."123" into the char preInput as one assignment? I need the vector to receive the numbers separately rather than all together as one element. To reiterate, if the user enters "123" userInputs[0] should be 1, userInputs[1] should be 2...and so on.
Essentially, the only thing that needs to be changed is that the while(cin>>preInput){} loop must break when the user hits enter.
Read a line with getline, then split that line up using istringstream.
std::string line;
std::getline(std::cin, line);
std::istringstream iss(line);
while(iss>>preInput){
if(preInput == 'Q' || preInput == 'q') break;
int input = (int) preInput - '0';
userInputs.push_back(input);
}
Or, since you're just looking at one character at a time, you can just look directly at the characters of the string.
for (char c : line)
{
if (c == 'Q' || c == 'q') break;
int input = c - '0';
userInputs.push_back(input);
}

Palindrome tester has logic flaws

This is just a basic palindrome tester for my C++ class, and there appears to be issues.
I already know that I have two separate flaws in here somewhere. At least one, I strongly suspect, is a logic issue. The first problem is that it runs fine the first time through, but when the loop initiates, it doesn't ask for user input to put in a new line to test as a palindrome, it simply retests the old one. The second issue is, I assume, that it is testing spaces, which I base off the fact that it's giving 'hannah' back as good, but 'never even or odd' comes back bad. This one I just don't know how to fix.
#include <iostream>
#include <string>
using namespace std;
int main()
{
bool repeater = true;
do
{
string palindroneCheck;
bool palindronity = true;
cout << "Please enter a line to test for palindromity.\n";
getline(cin, palindroneCheck);
int stringSize = palindroneCheck.size();
int cutOff = stringSize/2;
for (int palindroneLength = 0; palindroneLength < cutOff; palindroneLength++)
{
if (palindroneCheck[palindroneLength] != palindroneCheck[stringSize - palindroneLength -1])
{palindronity = false;
break;}
}
if(palindronity == true)
cout << "Congratulations! This line is a palindrone!\n\n";
else
cout << "Sorry, but this is not a palindrone.\n\n";
palindroneCheck.clear();
char repeat;
cout << "Would you like to try another line? Y/N\n";
cin >> repeat;
if (repeat == "n" || repeat == "N")
repeater = false;
} while (repeater == true);
}
OK, you are right about the spaces. Your code will demand that spaces are in the same location like every other character.
The other bug seems more subtle: it's where you ask to repeat or not.
Why? Because it asks, you enter 'n' and then 'enter'
The cin >> repeat only reads the 'n', but not the 'enter'
so the next time you do `readline(cin,PalindromCheck)' it will read an empty string.
Try to write palindromCheck just after reading it. You'll see.
The reading issue of getline is solved by comments. For the whitespaces, you can tackle it by removing all the spaces inside string palindroneCheck,
std::string::iterator new_end = std::remove(palindroneCheck.begin(), palindroneCheck.end(), ' ');
std::string palindroneCheckWithoutSpaces(palindroneCheck.begin(), new_end);
Then you use palindroneCheckWithoutSpaces to do the Palindrone test.
int stringSize = palindroneCheckWithoutSpaces.size();
int cutOff = stringSize/2;
for (int palindroneLength = 0; palindroneLength < cutOff; palindroneLength++)
{
if (palindroneCheckWithoutSpaces[palindroneLength] != palindroneCheck[stringSize - palindroneLength -1])
{palindronity = false;
break;}
}
if(palindronity == true)
cout << "Congratulations! This line is a palindrone!\n\n";
else
cout << "Sorry, but this is not a palindrone.\n\n";
(you need header algorithm to use remove)
Update:
std::remove remove an element from the input range (this is defined by begin and end here) based on the value you passed in , here is the whitespace ' '. Then it return the new end of the changed range (since you delete something, the range becomes smaller). The new range starts with begin and ends with the returned value.
So the second line you create a new string based on the new range.