#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char str[80];
int i=0;
cout<<"Enter the String ";
gets(str);
for (int j=0;str[j]!='\0';j++)
if (str[i]=='A'||'E'||'I'||'O'||'U')
i++;
cout<<"Number of vowels is: "<<i;
}
Here i am check element in String for Vowel, can anyone please suggest alternate method for this? I need to count number of vowels in string.
This code is working perfect for me, just need to find alternate method where i don't have to type too much "||" and 'a' and 'A' differently.
if (str[i]=='A'||'E'||'I'||'O'||'U')
this is wrong
should be like this:
if(str[i]=='A' || str[i]=='E'||str[i]=='I'||str[i]=='O'||str[i]=='U')
and also take care of case sensitiveness
str[i]=='A'||'E'||'I'||'O'||'U'
always returns true, because 'E' is always true. You're looking for
strchr("AEIOU", str[j])
Note the j, you got the loop variable wrong.
(Also, in C++, you'll want to use iostreams and getline instead of cstdio and fgets.)
A more C++-ish solution:
std::string vowels("aAeEiIoOuU");
for (int j=0;str[j]!='\0';j++)
{
if ( vowels.find(str[j]) != std::string::npos )
i++;
}
inline bool is_vowel(char a)
{
a=std::tolower(a);
switch(a)
{
case 'a': case 'e':
case 'i': case 'o':
case 'u':
return true;
}
return false;
}
int main()
{
std::string line;
std::cout << "enter text" << std::endl;
std::getline(std::cin, line);
int vowel=std::count_if(line.begin(), line.end(), is_vowel);
std::cout << "Number of vowels: " << vowel << std::endl;
}
Or use a table:
#include <iostream>
#include <string>
int main()
{
char list_v[256] = { 0 };
list_v['a'] = list_v['e'] = list_v['i'] = list_v['o'] = list_v['u'] = 1;
list_v['A'] = list_v['E'] = list_v['I'] = list_v['O'] = list_v['U'] = 1;
std::string str = "a sentence here";
uint32_t cnt = 0;
for (uint32_t i = 0; i < str.length(); i++)
cnt += list_v[str[i]];
std::cout << "found " << cnt << std::endl;
return 0;
}
or use map for the same purpose, or a c++ array/vector, people don't like c arrays here. This only works for ASCII of course.
Way? or syntax?
i think its a syntax error.. it should be like
if(str[i]=='A' || str[i]=='E'||str[i]=='I'||str[i]=='O'||str[i]=='U')
If you are asking about a better way, i don't think there is any..
You are doing in O(n) complexity, which is good enough i guess.! Even if you use hashing, you'll have to hash all the n characters in a string..
Related
I've searched all over to try to answer my own questions, but I'm hitting a wall here. I've been working on this same exercise for three days and getting frustrated, hence my very first post! This is a school assignment, but I really want to understand why this isn't working. When I use input "bob" it returns "bob is a palindrome" as expected. When I input "bobby" it returns "bobby is not a palindrome" as expected. All good there. It took me forever to figure out how to remove spaces from my input when using the sentence "never odd or even" but I managed to do that successfully, too. But here's the rub: (1) even after the spaces are removed, it seems to think that "neveroddoreven" is NOT a palindrome - why? What am I missing? Additionally, and this is probably a stupid question (but this is my first foray into programming and I'm a total newbie), how do I get it to output the original userInput before I removed the spaces in the final output? Currently the below code outputs "neveroddoreven is not a palindrome". Thanks in advance for any pointers you can give me.
#include <string>
#include <cctype>
using namespace std;
int main() {
string userInput;
int startInput;
bool isPalindrome = true;
getline (cin, userInput);
startInput = userInput.length();
for(int i = 0; i<userInput.length(); i++)
if(userInput[i] == ' ') userInput.erase(i,1);
for (int i = 0; i<(startInput / 2); i++){
if (userInput[i] != userInput[(startInput -1 ) -i])
isPalindrome = false;
}
if (isPalindrome){
cout << userInput << " is a palindrome" << endl;
}
else {
cout << userInput << " is not a palindrome" << endl;
}
return 0;
}
After you erase all the spaces, startInput no longer refers to the actual length of the string. That means this comparison:
if (userInput[i] != userInput[(startInput -1 ) -i])
is not comparing the correct characters.
You can fix this by adding this line:
startInput = userInput.length();
after doing the erasing.
Here's a demo.
Also, in your erase code, this comparison i<userInput.length() is not a good idea, since you are comparing a signed and unsigned value. Also, you don't erase adjacent spaces. A simpler way to do that would be:
userInput.erase(std::remove(std::begin(userInput), std::end(userInput), ' '),
std::end(userInput));
As others have pointed out, the problem is that startInput doesn't take into account that you erase some spaces. So move the the line startInput = userInput.length(); so that it is just after the erase-loop.
An alternative solution that will not change the original input could be:
#include <iostream>
#include <string>
int main()
{
std::string userInput;
std::string userInputNoSpace; // Use one more string
int startInput;
bool isPalindrome = true;
std::getline(std::cin, userInput);
// Copy all characters that are NOT space to the new string
for (auto c : userInput)
{
if (c != ' ')
{
userInputNoSpace += c;
}
}
startInput = userInputNoSpace.length();
for (int i = 0; i<(startInput / 2); i++)
{
if (userInputNoSpace[i] != userInputNoSpace[(startInput -1 ) -i])
{
isPalindrome = false;
break;
}
}
if (isPalindrome)
{
std::cout << userInput << " is a palindrome" << std::endl;
}
else
{
std::cout << userInput << " is not a palindrome" << std::endl;
}
return 0;
}
Input:
never odd or even
Output:
never odd or even is a palindrome
I'm new to C++ and coding. I tried to make a hangman game as a beginner project. The problem I have is that the game only works when the letters of the word is typed in order. If the word is "flow" for instance, I have to type each letter consecutively (f,l,o,w). Any other variations is not accepted and I don't know why. I need help debugging this issue. I'm not sure if .replace is the method I should be using here. I found this method on the internet and I thought it would do what I needed it to do.
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
using namespace std;
string getString(char guess) {
string s(1, guess);
return s;
}
int main() {
unsigned int seed;
int randomNumber = 0;
char guess;
string underscore;
seed = time(0);
cout << "Hangman game\n";
srand(seed);
randomNumber = (rand() % 5);
string wordList[5] = {"closet", "flow", "sheep", "see", "chocolate"};
string word = wordList[randomNumber];
int wordLength = word.length();
cout << "The word has " << wordLength << " letters\n";
for (int x = 0; x < wordLength; x++) {
underscore += "_ ";
}
cout << underscore << endl;
string holder = underscore;
for (int j = 0; j < wordLength; j++) {
cout << "\n\nType in a letter: ";
cin >> guess;
if (guess == word[j]) {
size_t found = word.find(guess);
holder.replace(found, 2, getString(guess));
cout << "\n";
word.replace(found, 1, "*");
cout << holder;
}
else {
}
}
return 0;
}
Here are some observations that might help you:
Don’t declare all variables at the top of your function. Declare them as you need them.
Avoid hard-coding (wordList[5]). Add as many as strings as you need in your array. Use the following to find out how many are (see sizeof):
string wordList[] = { "closet", "flow", "sheep", "see", "chocolate" };
size_t wordCount = sizeof wordList / sizeof wordList[0];
You do not need to manually fill the underscore string. Use the following constructor:
string underscore(word.length(), '_');
The user might enter uppercase letters. Convert them to lowercase. Otherwise you will not find them:
guess = tolower(guess);
You do not need fancy functions to find out where the entered character is located. Just use a loop:
//...
bool found = true;
for (int i = 0; i < word.length(); i++)
{
if (word[i] == guess) // is the letter at position i the same as the one entered?
underscore[i] = guess; // replace it
if (underscore[i] == '_')
found = false;
}
if (found)
{
cout << "Good job!" << endl;
return 0;
}
//...
As a homework exercise we were asked to use strchr to count the amount of times a single letter appears in a string of text. It needs to count upper or lower cases as equal. It was suggested we use some sort of bit operations.
I managed to get a working program.
But i would like to make the program more interactive by allowing me to use a cin to input the string instead of typing the string directly into the source code (Which was asked by the exercise).
Is it possible to do this? Or is it not possible in the way i wrote this code.
#include <iostream>
#include <cstring>
using namespace std;
int main(){
const char *C = "This is a necesarry test, needed for testing.";
char target = 'A';
const char *result = C;
const char *result2;
int count = 0;
int j[26] ={0};
//================================================================================================================================================
for(int i = 0; i <= 51; i++){
if (i == 26){
target = target + 6;
}
result2 = strchr(result, target);
while(result2 != NULL){
if (result2 != NULL){
result2 = strchr(result2+1, target);
if (i <= 25){
j[i] = j[i] +1;
}
if(i > 25){
j[i-26] = j[i-26] +1;
}
cout << target << "\t";
}
}
cout << target << endl;
target++;
}
char top = 'a';
for(int o = 0; o<= 25; o++){
cout << "________________________________\n";
cout << "|\t" << top << "\t|\t" << j[o] << "\t|" << endl;
top++;
}
cout << "________________________________\n";
}
Simply use getline() to get a string of characters from the console. Using getline you can also consider the spaces in the user input.
string input;
getline(cin, input);
Now to use this with the strchr functionn you simply have to convert this into a C Type string which can be done as follows :
input.c_str
This returns a C type string so you can put this as an arguement to the function,
You will need
#include <string>
I have a C++ program that finds and erases any vowels in a giving string. The only problem is, it doesnt work and I can't find the reason why. I have to use 2 functions that removes all the vowels and another that determines if a character is a vowel and all of this should operate in a loop.
This is my code:
#include <iostream>
#include <string>
using namespace std;
bool isA_Vowel(string s);
string remov(string s);
int main()
{
string s;
string ans = "y";
while((ans == "Y") || (ans == "y"))
{
cout << "Please enter a word or a series of letters: ";
cin >> s;
cout << "Old: " << s << endl;
cout << "New: " << remov(s) << endl;
cout << "Would you like to go again? <y/n> ";
cin >> ans;
}
}
bool isA_Vowel (string s)
{
if (s == "a" || s == "e"|| s == "i" || s == "o" || s == "u" || s == "A"
|| s == "E" || s == "I" || s == "O" || s == "U")
{
return (true);
}
else
{
return (false);
}
}
string remov(string s)
{
for (unsigned int i = 0; i < s.length(); ++i)
{
if (isA_Vowel(s))
{
s.erase(i,1);
}
}
return(s);
}
I had it working before, but now it won't run properly and erase all the vowels.
Any suggestions or tips would be awesome!
Thank you in advance!
Alright well I'm impantient and in a good mood, so here.
#include <iostream>
#include <string>
bool isVowel(char ch);
void removeVowels(std::string& str);
int main()
{
std::string Text = "";
std::cout << "Please enter a string, what ever you like: ";
std::getline(std::cin, Text);
removeVowels(Text);
std::cout << Text << std::endl;
return 0;
}
bool isVowel(char ch)
{
switch (ch)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
return true;
default:
return false;
}
}
void removeVowels(std::string& str)
{
int len = str.length();
int index = 0;
while (index < len)
{
if (isVowel(str[index]))
{
str = str.substr(0, index) + str.substr(index + 1, str.length());
len = str.length();
}
else index++;
}
}
The issue you were having was
I had it working before, but now it won't run properly and erase all the vowels. Any suggestions or tips would be awesome! Thank you in advance!
In your for loop don't use an unsigned int, just use an int!
Generally speaking you shouldn't really just return true or false "straight" as you've done here, there are a variety of reasons why, and I'm sure your professor will cover them. But for all intents and purposes declare a boolean variable (bool vowel = true) is an example of one and you can use that in your return.
Because you're using an if statement on it's own with no looping structure (and even with one you'd still have issues) it's only executing once which means at best it would only find one vowel. You're also returning true but you're not providing logic to handle it.
For instance what do you want to occur when it returns true, and what do you want it to do when it returns false?
You're using cin which does not and will not take multiples words (white spaces) use getline(cin, input); (input being your input variable)
I actually misread your code and I've changed my comment here to clarify. You say in your function to remove the vowel s.erase(i, 1); essentially what you're doing is starting at position 0 in your string iterating forward by 1 position and deleting the starting and ending point (starting point being 0 ending point being 1).
Remember the first position is 0 not 1.
If you've got questions about the code I provided you please let me know and I'll explain it to you!
When I print out text2 I see that it is definitely not the reverse of the string I gave it and I'm not sure why that is. When I put in "test" I get stuff like "ȍ\2200+". Can I use strncpy on char arrays? Maybe it needs to be done with a loop - not sure. Any help would be appreciated. :)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char text[79], text2[79];
bool input = true;
while (input) {
cout << "Please give me a line of text to examine: ";
cin.getline(text, 79);
for(int i = 0; i < strlen(text); i++ )
cout << text[i];
// test to see if it is a palindrome
strncpy(text, text2, 80);
reverse(text2, text2 + strlen(text2));
printf("%s", text2); `// when I print this out I get something odd`
if (strcmp(text, text2) == 0)
cout << " is a palindrome!" << endl;
else
cout << " is not a palindrome." << endl;
if (strcmp(text, "END") == 0)
input = false;
else
cout << "\ntype END to exit the program" << endl;
} // end while loop
} // end main
It seems you're using strncpy in a wrong way: you probably want to copy text into text2, not the other way around.
There's a much simpler way to test whether a string is a palindrome, namely:
bool is_palindrome(const char* s, size_t n) {
size_t i, j;
i = 0, j = n-1;
while (i < j && s[i++] == s[j--])
;
return i >= j;
}
Why not use std::vector<char> and std::reverse from <algorithm> to handle your problem?
I would do something like below: (note that I'm using C++11 range-based for loop and auto which you can change to a regular for loop and use std::string line if you don't have a compiler supporting this).
int main()
{
cout << "Please give me a line of text to examine: ";
auto line = ""s;
getline(cin, line);
// Push back every character to the vector
vector<char> vtext;
for (const auto &elem : line)
vtext.push_back(elem);
// Create a copy of the vector<char> and reverse the copy
vector<char> vtext_reversed{vtext};
reverse(begin(vtext_reversed), end(vtext_reversed));
// Print the line reversed
cout << "\nThis is the line reversed: ";
for (const auto &elem : vtext_reversed)
cout << elem;
}
Typically you'll see this reversal technique for char*:
void reverse(char* s) {
if(!s) return;
size_t n = strlen(s);
for(size_t i = 0; i < n/2; ++i) {
char tmp = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = tmp;
}
}
This will not work, however, with non-ASCII characters. The reason is that non-ASCII characters require multiple bytes to represent.
You will need to use wide characters to handle multi-byte codepoints, but the logic should follow above.