I'm trying to create a function that will replace 0's, 1's, or 2's with spaces in a string. I'm going about it by iterating through the string and comparing each individual character.
My function will work if I compare str_in[i] == '0', but if I add the or statement it returns nothing.
Snippet:
string omit_num( string ) {
int i ;
str_len = str_in.length();
str_out = "" ;
for( i = 0 ; i < str_len ; i ++ ){
cout << str_in[i] << endl;
if ( str_in[i] == '0' || '1' || '2')
app = " " ;
else
app = str_in[i];
str_out.append(app) ;
}
return str_out;
}
You need
if ( str_in[i] == '0' || str_in[i] =='1' || str_in[i] =='2')
You will have to repeat the test each time, '1', '2' on their own are basically small ints and evaluate to true. It should look like the following:
if (str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2')
The expression str_in[i] == '0' || '1' || '2' contains three separate expressions:
str_in[i] == '0'
'1'
'2'
According to any ASCII chart, '0' has a value of 48, '1' is 49, '2' is 50. So the last two expressions are always non-zero (and therefore always true).
You probably wanted str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2'
if (str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2')
or alternatively
switch (str_in[i]) {
case '0':
case '1':
case '2': app = " " ;
break;
default: app = str_in[i];
}
Your if statement reads as follows: If the character at i is equal to '0', or '1' is true, or '2' is true. As '1' and '2' both evaluate to a non zero integer, it will always be true.
What you want is: str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2'
'1' is '1' therefore '1' evaluates to true. You must make new, complete, statements with every operator.
try this:
if ( str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2' )
Not sure about the logic overall, but the logic here specifically is wrong. Replace
if ( str_in[i] == '0' || '1' || '2')
with
if ( str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2')
Change your if statement to:
if ( str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2') {
...
}
string omit_num( string ) {
int i ;
str_len = str_in.length();
str_out = "" ;
for( i = 0 ; i < str_len ; i ++ ){
cout << str_in[i] << endl;
if ( str_in[i] == '0' || '1' || '2')
app = " " ;
else
app = str_in[i];
str_out.append(app) ;
}
return str_out;
}
this would work as the following:
string omit_num( string ) {
int i ;
str_len = str_in.length();
str_out = "" ;
for( i = 0 ; i < str_len ; i ++ ){
cout << str_in[i] << endl;
if ( (str_in[i] == '0') || (str_in[i] == '1') || (str_in[i] == '2'))
app = " " ;
else
app = str_in[i];
str_out.append(app) ;
}
return str_out;
}
You need to apply the equality operator in each || expression:
if (str_in[i] == '0' || str_in[i] == '1' || str_in[i] == '2')
If you're using c++, use the standard library already:
std::replace_if( s.begin(), s.end(), [](char a){return a=='0'||a=='1'||a=='2';}, ' ');
Related
I am practicing a coding challenge where I have to reverse the vowels in a string.
My first approach failed because of exeeding Time limit. Here is my first approach using string iteration to reverse the vowels in a string.
string reverseVowels(string s) {
string str = "";
//storing the vowels from the string into another string
for (auto x : s)
if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u' || x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U')
str = str + x;
//swapping the vowels
int count = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U')
{
s[i] = str[count];
count++;
}
}
return s;
}
My second approach using the char vector iteration had passed all the tests. Here is my second approach
class Solution {
public:
string reverseVowels(string s) {
vector<char> v;
//storing the vowels from the string into vector
for (auto x : s)
if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u' || x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U')
v.push_back(x);
//swapping the vowels
int count = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U')
{
s[i] = v[count];
count++;
}
}
return s;
}
};
Could you explain why my first method failed the tests but second method passed the tests
Replace str = str + x; with str.push_back(x); or str += x;, and you'll likely see the same performance as with vector.
str = str + x; makes a copy of str, appends the character to that copy, then makes another copy when assigning back to str. As a result, your algorithm is quadratic, for no good reason.
It's because you're doing str = str + x, that creates an unnecessary copy of str, but std::vector::push_back or std::string::push_back appends a character to the vector or string, which is much faster than creating a copy of str.
str = str + x
this creates an additional copy of str while copying.
std::vector::push_back
this straight appends to the vector string
While user inputs 10 alphabets, program should tell how many of them are vowels. I have written this code:
while (count<10)
{
cin >> n;
count++;
if (n == 'A' || n == 'a' && n == 'E' || n == 'e' && n == 'I' || n == 'i' && n == 'O' || n == 'o' && n == 'U' || n == 'u')
{
total++;
}
}
cout << total << endl;
This generates output of 0 even if there are vowels entered by user. something wrong?
Let's start by cutting down the condition down a bit, to only look at a and e
if (n == 'A' || n == 'a' && n == 'E' || n == 'e')
and then only considering the lowercase letters for simplicity (but retains the problem)
if (n == 'a' && n == 'e')
if you read this out loud it says "if n is 'a' AND n is 'e'". The "AND" (from the && operator) means that both conditions must be true. You've created an impossible condition here, if n is 'a', then it is not 'e', so you get if (true && false) - which is false. If n is 'e', then it is not 'a', so you get if (false && true).
Simply replace all of your && (and) operators with || (or) operators to have the condition be true if at least one of your equality comparisons is true.
if (n == 'A' || n == 'a' || n == 'E' || n == 'e'
|| n == 'I' || n == 'i' || n == 'O' || n == 'o'
|| n == 'U' || n == 'u')
There are some ways to simplify the condition.
One is to add a #include <cctype> and use std::tolower to convert n to lowercase, then you only need to compare against lowercase characters.
n = std::tolower(n);
if (n == 'a' || n == 'e' || n == 'i' || n == 'o' || n == 'u')
Another, less repetitive approach is to create a std::string with all the vowels in it, and then see if it contains n, #include <string> up top.
std::string vowels = "aeiouAEIOU";
while (/*...*/) {
// ...
if (vowels.find(n) != std::string::npos) {
++total;
}
}
As n314159 pointed out, if you are using C++17 or later, you can use a std::string_view instead, which is cheaper. #include <string_view>
static constexpr std::string_view vowels = "aeiouAEIOU";
while (/*...*/) {
// ...
if (vowels.find(n) != std::string_view::npos) {
++total;
}
}
I recommend using a switch statement with fall-through, which is more readable but also potentially more efficient (may be implemented with jump table).
int count = 10;
while (count--) {
switch(std::tolower(n)) {
case 'a': case 'e':
case 'i': case 'o':
case 'u': total ++; break;
default:;
}
}
These change the array that I print to the screen. direc is an input before this. However, when array[1][2] == '#', it still moves '#' to array[1][0].
if (array[1][1] == '#' && direc == 'A' || direc == 'a' ) {
array[1][1] = '_';
array[1][0] = '#';
}
else {
if (array[1][1] == '#' && direc == 'D' || direc == 'd' ) {
array[1][1] = '_';
array[1][2] = '#';
}
else {
if (array[1][2] == '#' && direc == 'A' || direc == 'a' ) {
array[1][1] = '#';
array[1][2] = '_';
}
}
}
You can either add parentheses, as already noted in the comments, like this
if (array[1][1] == '#' && (direc == 'A' || direc == 'a' )) {
Alternatively you could use std::tolower in which case you no longer nee
if (array[1][1] == '#' && std::tolower(direc) == 'a') {
You could still add extra parentheses if you are not comfortable that operator && is lower precedence than operator ==
(the full table of operator precedences can be seen here)
help! im trying to replace 'a' and 'e' with ' ' in my array but it keeps replacing all of the array instead.
for(int x = 0; x < array_length); x++)
{
if(city_name[x] == 'a' || 'e')
city_name[x] = " ";
}
if(city_name[x] == 'a' || 'e')
should be
if(city_name[x] == 'a' || city_name[x] == 'e')
Your code is equivalent to
if( ( city_name[x] == 'a' ) || 'e')
which does city_name[x] == 'a' and then checks the result of that statement || 'e'
First of all the loop is wrong. it contains a typo
for(int x = 0; x < array_length); x++)
^^^
Remove the redundant parenthesis.
Also this condition
city_name[x] == 'a' || 'e'
is always equal to true because it is equivalent to
( city_name[x] == 'a' ) || 'e'
And instead of string literal " " you have to use character literal ' '
The correct loop can look like
for ( int i = 0; i < array_length; i++ )
{
if ( city_name[i] == 'a' || city_name[i] == 'e' ) city_name[i] = ' ';
}
Take into account that there is standard algorithm std::replace_if declared in header <algorithm> that can be used instead of the loop. For example
std::replace_if( city_name, city_name + array_length,
[]( char c ) { return c == 'a' || c == 'e'; },
' ' );
Hello i don't know how to fix my program to find how many evens, odds, vowels and consonants are in my string.
The program compiles and runs but i never get any vowels or consonants and everything else is added in either evens or odds (even characters).
Edit 1: By evens and odds i mean like if the user types in the string John123 i want to find how many characters are vowels in this case 1 the 'o' how many are consonants in this case 3 the 'J', 'h', 'n' how many are evens in this case 1 the '2' and how many are odds in this case 2 the '1' and the '3'.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s1;
int evens = 0; //
int odds = 0; //
int vowels = 0; //
int consonants = 0; //
cout << "Please type in Something: ";
getline(cin, s1);
cout << "You typed: " << s1 << endl;
for(int i = 0; i < s1.size(); ++i)
{
if((s1[i] % 2) == 0 )
{
++evens;
}
else if((s1[i] % 2 ) != 0) // What would an algorithm (formula) be to find when a number is odd without the not-equals != ?
{
++odds;
}
else if(s1[i] == 'A' || 'a' || 'E' || 'e' || 'O' || 'o' || 'I' || 'i' || 'U' || 'u')
{
++vowels;
}
else if(s1[i] == 'Q' || 'W' || 'R' || 'T' || 'Y' || 'P' || 'S' || 'D' || 'F' || 'G' || 'H' || 'J' || 'K' || 'L' || 'Z' || 'X' || 'C' || 'V' || 'B' || 'N' || 'M'||
'q' || 'w' || 'r' || 't' || 'y' || 'p' || 's' || 'd' || 'f' || 'g' || 'h' || 'j' || 'k' || 'l' || 'z' || 'x' || 'c' || 'v' || 'b' || 'n' || 'm')
// I specify every letter so that it dosn't pick whitespaces, symbols etc.
{
++consonants;
}
}
cout << "Evens in string are: " << evens << "\nOdds in string are: " << odds << "\nVowels in string are: " << vowels << "\nConsonants in string are: " << consonants;
return 0;
}
if((s1[i] % 2) == 0 )
This code is not correct. You are modulating the character, which isn't what you want. You want to first convert the character to an integer using atoi or something like that, I can't remember the function. (Just look up string to int c++). Then, once you've converted the character to an integer, then you can modulate it correctly.
Also, your || syntax is totally wrong, as Jongware mentioned. You need to have an == comparison for each character.
Should look like this (very long):
(s1[i] == 'A' || s1[i] == 'a' || s1[i] == 'E' || s1[i] == 'e' || s1[i] == 'O' || s1[i] == 'o' || s1[i] == 'I' || s1[i] == 'i' || s1[i] == 'U' || s1[i] == 'u')
You might want to store s1[i] in a char beforehand so it's more concise.
And you should place your character testing BEFORE the odd/even testing, so that you don't accidentally try and convert h or another non-numeric character to an integer.
A char is a number. For example, a is (on most computers) the ASCII code 97. So either your even test or your odd test will always match. You need to rearrange your if blocks.
Also, your character tests don't do what you intended. s1[i] == 'A' || 'a' tests as true whenever s1[i] is equal to 'A' or whenever 'a' as a number is not zero. But 97 is never zero, so that test will always result in true. You need code more like s1[i] == 'A' || s1[i] == 'a', testing the s1[i] value each time.
(One way to make things simpler: Once you know the character is not a vowel, you can test for an ASCII consonant with ((s1[i] >= 'a' && s1[i] <= 'z') || (s1[i] >= 'A' && s1[i] <= 'Z')).)
You have basically two problems:
Characters are interpreted as numbers, taking into account the character code. When you are checking whether the character is even or odd, you are checking its character code which will always be either event of odd, this is why your code will always enter into the first or second case. You must check whether your character is digit and if so, you must check whether it is even
Your OR is incorrect, see Ruby van Soelen's answer
Suggested, untested code:
for(int i = 0; i < s1.size(); ++i)
{
if (isdigit(s1[i])) {
if ((s1[i] == '0') || (s1[i] == '2') || (s1[i] == '4') || (s1[i] == '6') || (s1[i] == '8'))
{
++evens;
}
else // What would an algorithm (formula) be to find when a number is odd without the not-equals != ?
{
++odds;
}
}
else
{
if(s1[i]=='A' || s1[i]=='a' || s1[i]=='E' || s1[i]=='e' || s1[i]=='O' || s1[i]=='o' || s1[i]=='I' || s1[i]=='i' || s1[i]=='U' || s1[i]=='u')
{
++vowels;
}
else if(s1[i]=='B' || s1[i]=='b' || s1[i]=='C' || s1[i]=='c' || s1[i]=='D' || s1[i]=='d' || s1[i]=='F' || s1[i]=='f' || s1[i]=='G' || s1[i]=='g' || s1[i]=='H' || s1[i]=='h' || s1[i]=='J' || s1[i]=='j' || s1[i]=='K' || s1[i]=='k' || s1[i]=='L' || s1[i]=='l' || s1[i]=='M' || s1[i]=='m' || s1[i]=='N' || s1[i]=='n' || s1[i]=='P' || s1[i]=='p' || s1[i]=='Q' || s1[i]=='q' || s1[i]=='R' || s1[i]=='r' || s1[i]=='S' || s1[i]=='s' || s1[i]=='T' || s1[i]=='t' || s1[i]=='V' || s1[i]=='v' || s1[i]=='X' || s1[i]=='x' || s1[i]=='Y' || s1[i]=='y' || s1[i]=='Z' || s1[i]=='z')
// I specify every letter so that it dosn't pick whitespaces, symbols etc.
{
++consonants;
}
}
}
Your || syntax is making no sence, what you currently have is something like this
else if(s1[i] == 'A' || 'a' || 'E' || 'e' || 'O' || 'o' || 'I' || 'i' || 'U' || 'u')
while it should be like this:
else if(s1[i]=='A' || s1[i]=='a' || s1[i]=='E' || s1[i]=='e' || s1[i]=='O' || s1[i]=='o' || s1[i]=='I' || s1[i]=='i' || s1[i]=='U' || s1[i]=='u')
Expression in the else-if statement will be always equal to true
else if(s1[i] == 'A' || 'a' || 'E' || 'e' || 'O' || 'o' || 'I' || 'i' || 'U' || 'u')
becuase it is equivalent to
( s1[i] == 'A' ) || 'a' || 'B' /*...*/
where 'a' as it is not equal to zero evaluates to true.
So you have to write at least like
s1[i] == 'A' || s1[i] == 'a' || s1[i] == 'B' /*...*/
Also take into account that for example character 'B' though is not a digit but its code is even. So you will get a wrong result if will start checks from statement
if((s1[i] % 2) == 0 )
You should check at first whether the character is a digit. Also you could define an array of vowels and consonants and use standard function strchr that to check whether a character is a vowel or consonant.
For example
#include <iostream>
#include <string>
#include <cctype>
//...
const char *alpha_vowels = "AEIOU";
const char &alpha_consonants = "BCD...";
//...
if ( std::isdigit( s[i] ) )
{
s[i] % 2 == 0 ? ++evens : ++odds;
}
else if ( std::strchr( alpha_vowels, std::toupper( ( unsigned char )s[i] ) ) != nullptr )
{
++vowels;
}
else if ( std::strchr( alpha_consonants, std::toupper( ( unsigned char )s[i] ) ) != nullptr )
{
++consonants;
}
In addition to the other answers, here's a simpler way to accomplish the same thing.
std::set<char> vs{'a', 'o', 'u', 'e', 'i'};
for (auto&& c : s1) {
if (std::isdigit(c))
if ((c - '0') % 2 == 0) // Trick to convert numeric char -> int.
++evens;
else
++odds;
else if (std::isalpha(c))
if (vs.count(std::tolower(c)))
++vowels;
else
++consonants;
}