-3

Here is my code:

#include <iostream>
#include <string>
#include<bits/stdc++.h>
using namespace std;

int main() 
{
    int n;
    cin >> n;

    while(n--)
    {
        string str;
        char a[] = {'a','e','i','o','u','A','E','I','O','U'};
        getline(cin, str);

        for(int i=0 ;i<str.length(); i++)
        {
            for(int j=0; j<10; j++)
            {
                if(str[i]==a[j])
                {
                    cout << str[i];
                }
            }
        }
        cout << "\n"; 
    }
    return 0;
}

Test cases are :

HmlMqPhBfaVokhR 
wdTSFuI 
IvfHOSNv 

I am not removing anything but I am printing only vowels. But, some test cases didn't pass. Maybe this code doesn't work on multiple test cases.

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • a) you are not removing anything from the string b) what are the test cases? c) you should include `` not `` – 463035818_is_not_an_ai Jun 06 '18 at 07:50
  • What's the description and what's the problem? – rsy56640 Jun 06 '18 at 07:52
  • 2
    One bug is, you need to `ignore()` after `cin>>n;`, otherwise `getline(cin, str);`, will not get anything. and this is not what you should do : `#include` – JeJo Jun 06 '18 at 07:52
  • Test cases are : HmlMqPhBfaVokhR wdTSFuI IvfHOSNv I updated to but problem is not solved. I am not removing anything but I am printing only vowels. – Priyam Rajvanshi Jun 06 '18 at 07:52
  • 2
    @PriyamRajvanshi Edit your question with test cases, not in comments. – JeJo Jun 06 '18 at 07:53
  • btw in general your [mcve] is more selfcontained if you put the input hardcoded in the code instead of using user input, on the other hand it might be that the bug is in how you take the user input, and on the other other hand you better seperate input and logic anyhow (ie make a function `remove_consonants` that takes a `string` as parameter and can be tested independent of where that string is coming from) – 463035818_is_not_an_ai Jun 06 '18 at 07:55
  • 1
    @JeJo can you provide me the code please? – Priyam Rajvanshi Jun 06 '18 at 07:59
  • 1
    Check this out [Using getline(cin, s) after cin](https://stackoverflow.com/q/5739937/1332041) – acraig5075 Jun 06 '18 at 08:01
  • 1
    Now do you want to really remove the vowels or do you just want to print out the input without them? – Aconcagua Jun 06 '18 at 08:07
  • You need to show the tests (possibly only the failing tests). Without that, your question is incomplete. – Toby Speight Jun 06 '18 at 08:18

3 Answers3

3

Try this for proper console in :

int main()
{
    int n;
    std::cin >> n;
    std::cin.ignore();   // fix
    /* remaining code */
    return 0;
}

> To find the vowels in a string

On way of finding the vowels in a string is using a std::binary_search each character of the given string in a vowel table.

  1. Make a sorted array of char s of all vowels(i.e. vowels array).
  2. For each char of the input string, std::binary_search in the vowels array.
  3. If std::binary_search returns true(meaning the char is an vowel), print the char of the string.

Following is the example code! (See live online)

#include <iostream>
#include <string>
#include <algorithm> // std::for_each, std::binary_search, std::sort
#include <array>     // std::array

int main()
{
    std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
    std::sort(a.begin(), a.end()); // need sorted array for std::binary_search

    const std::string str{ "HmlMqPhBfaVokhR wdTSFuI IvfHOSNv" };
    std::for_each(str.cbegin(), str.cend(), [&](const char str_char)
    {
        if (std::binary_search(a.cbegin(), a.cend(), str_char))
            std::cout << str_char << " ";
    });
    return 0;
}

Output:

a o u I I O

> To remove the vowels from a string

Use erase-remove idiom as follows(till ).

  1. Make a sorted array of char s of all vowels(i.e. vowels array).
  2. Using std::remove_if, collect the iterators pointing to the characters, which are vowels. A lambda function can be used as the predicate for std::remove_if, where the std::binary_search is used to check the char in the string exists in the vowels array.
  3. Using std::string::erase, erase all the collected characters(i.e. vowels) from the string.

Following is an example code! (See live online)

#include <iostream>
#include <string>
#include <algorithm> // std::sort, std::binary_search, std::remove_if
#include <array>     // std::array

int main()
{
    std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
    std::sort(a.begin(), a.end()); // need sorted array for std::binary_search

    std::string str{ "Hello World" };
    // lambda(predicate) to check the `char` in the string exist in vowels array
    const auto predicate = [&a](const char str_char) -> bool { 
        return std::binary_search(a.cbegin(), a.cend(), str_char);
    };
    // collect the vowels
    const auto vowelsToRemove = std::remove_if(str.begin(), str.end(), predicate);
    // erase the collected vowels using std::string::erase
    str.erase(vowelsToRemove, str.end());

    std::cout << str << "\n";
    return 0;
}

Output:

Hll Wrld

Since , one can use std::erase_if for this, which would be less error prone than the the above one. (See online live using GCC 9.2)

#include <iostream>
#include <string>    // std::string, std::erase_if
#include <array>     // std::array

int main()
{
    std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
    std::sort(a.begin(), a.end()); // need sorted array for std::binary_search

    std::string str{ "Hello World" };
    // lambda(predicate) to check the `char` in the string exist in vowels array
    const auto predicate = [&a](const char str_char) -> bool { 
        return std::binary_search(a.cbegin(), a.cend(), str_char);
    };

    std::erase_if(str, predicate); // simply erase

    std::cout << str << "\n";
    return 0;
}

> To remove the consonants from a string

To remove the consonants from the given string, in the above predicate negate the result of std::binary_search. (See live online)

const auto predicate = [&a](const char str_char) -> bool { 
    return !std::binary_search(a.cbegin(), a.cend(), str_char);
    //     ^^ --> negate the return
};

As side notes,

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • How do you know what “ascending order” is for the vector of characters? And how do you know that a binary search will be faster than a linear search for such a short list of characters? – Pete Becker Jun 06 '18 at 08:15
  • @PeteBecker do you agree **O(log10)** < **O(10)** ? if so binary search is better always. However, for a small array we can also do liner look ups, which in end effects will not be a big performance difference. – JeJo Jun 06 '18 at 08:24
  • If input is small enough, the sorting overhead even might consume all of the little benefit that possibly yet remains... Suppose the problem is just too simple for such an elaborate approach (but I like it...). – Aconcagua Jun 06 '18 at 08:32
  • @Aconcagua: regarding `std::sort()`, its true what you said. He could also use the sort before the loop, so that each time the sorting can be avoided. However, I just generalized the situation, which will be applicable to other characters which are not vowels. Furthermore, binary search is my habit. However, I found `strchr` also a good approach as the array is small. – JeJo Jun 06 '18 at 08:56
  • @JeJo -- binary search is better for **large inputs**. Asymptotic complexity is about **asymptotes**; it is not an absolute measure of performance. – Pete Becker Jun 06 '18 at 16:19
1

Apart from the std::getline problem already answered:

for(int i=0 ;i<str.length(); i++)
{
    for(int j=0; j<10; j++)
    {
        if(str[i] == a[j])
        {
            // this is the one you do NOT want to print...
            // cout<<str[i];
            // skip instead:
            goto SKIP;
        }
    }
    std::cout << str[i]; // output the one NOT skipped...
    SKIP: (void)0;
}

OK, don't want to start any discussion about usage of goto, there are many ways to avoid it, e. g. by packing the inner for loop into a separate (inline) function. You can have it easier, though, as there already exists such a function; code gets even easier with a range-based for loop:

for(auto c : str)
{
    if(!strchr("aeiouAEIOU", c))
    {
        std::cout << c;
    }
}

strchr (from cstring) returns a pointer to the first character in the string equal to the reference character - or nullptr if not found...

To really remove the vowels from the string in a modern C++ way, consider this:

str.erase(std::remove_if(
        str.begin(), str.end(),
        [](char c) { return strchr("aeiouAEIOU", c) != nullptr; }
    ), str.end());
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
0

Your code probably should looks like (please see comments inline):

#include <iostream>
#include <string>
using namespace std;

int main() {
    string vowels = "aeiouAEIOU";

    int n;
    cin>>n; // assume this stands for line count

    while(n-- >= 0)
    {
        string str, result;
        getline(cin, str);

        for(int i=0 ;i<str.length(); i++)
        {
            if (vowels.find(str[i]) != std::string::npos)
                result += str[i];   // add character to result if it is not consonant
        }
        cout<<result<<"\n"; // print result
    }

    return 0;
}
zhm
  • 3,513
  • 3
  • 34
  • 55
  • This code doesn’t fix the problem. All it does is complexity the code; it produces exactly the same output. – Pete Becker Jun 06 '18 at 08:12
  • @PeteBecker OP didn't actually explain the issue well. I figured out the line count is one less than it should be. Not sure if that is the problem. – zhm Jun 06 '18 at 08:26