Write a recursive, bool-valued function, containsVowel, that accepts a string and returns true if the string contains a vowel.
A string contains a vowel if:
The first character of the string is a vowel, or
The rest of the string (beyond the first character) contains a vowel

This is one of the recursion exercises I couldn't get right.
Any suggestions? Thanks!

My code:

    bool containsVowel (string s) {
        if (s.substr(0,1)=="a") return true;
        if (s.substr(0,1)=="e") return true;
        if (s.substr(0,1)=="u") return true;
        if (s.substr(0,1)=="o") return true;
        if (s.substr(0,1)=="i") return true;
        containsVowel (s.substr(1,s.length()-1));
    }

For starters, I would turn your testing into a series of if..else if statements, including the final recusive call. Then you need and else case that returns false.

hi, thanks for answering.
still get error from codeLab

    bool containsVowel (string s) {
        if (s.substr(0,1)=="a") return true;
        else if (s.substr(0,1)=="e") return true;
        else if (s.substr(0,1)=="u") return true;
        else if (s.substr(0,1)=="o") return true;
        else if (s.substr(0,1)=="i") return true;
        else 
            containsVowel (s.substr(1,s.length()-1));
        return false;
    }

this is the error message:

Remarks:

⇒ terminate called after throwing an instance of
'std::out_of_range'
⇒ what(): basic_string::substr

⇒ Your code had an error during execution

Still missing parts.

Base case - when string being examined is empty.

The recusive call needs to be in an if..else, and it's return needs to be returned.

The return false needs to be in an else block.

You are getting the out of bounds from line 8. Before you try to length() - 1, do a check to see if length == 0. If true, return false.

bool containsVowel (string s) 
{
    if (0 == s.length())
        return false;

    if ( (s.substr(0,1)=="a") || (s.substr(0,1)=="e") || (s.substr(0,1)=="i") ||
        (s.substr(0,1)=="o") || (s.substr(0,1)=="u") ) 
        return true;

    return containsVowel (s.substr(1, s.length() - 1));
}

I'll leave you to work out handling uppercase vowels.

The thinking mainly is wrong, because, on recursive calls, if indeed a vowel is found, it will still return false, because of the last condition. I suggest you take an extra variable, if allowed, which will carry the information:

void containsVowel (string s, bool &isIt) {
    if (s.empty()) return;
    if (s[0]=='a' || s[0]=='e' || s[0]=='u' || s[0]=='o' || s[0]=='i') isIt=true;
    containsVowel(s.substr(1, s.size()-1), isIt);
}

int main(){
    string a="bcdghijklmnpqrst";
    bool isIt=false;
    containsVowel(a, isIt);
    if (isIt) cout<<"True.\n";
    else cout<<"Not true.\n";
    return 0;
}

Let me explain a bit what I mean, regarding your function:

string a="bcdfghijklmnpqrst"

this string conains the vowel i.

when calling your function, eventually will return true from finding the vowel:
here are the recursive returns:


"t" return false
"st" return false
"rst" return false
"qrst" return false
"pqrst" return false
"npqrst" return false
"mnpqrst" return false
"lmnpqrst" return false
"klmnpqrst" return false
"jklmnpqrst" return false
"ijklmnpqrst" return true // we found a solution
"hijklmnpqrst" return false //here the return changes, because 'h' is not a vowel.
"ghijklmnpqrst" return false
"fghijklmnpqrst" return false
"dfghijklmnpqrst" return false
"cdfghijklmnpqrst" return false
"bcdfghijklmnpqrst" return false

So, even thou your word conains vowels, it will still return false.
Again, I don't know if your teacher allowes you to make it into a void, and take an extra value which will hold the information.

There is no need for additional variables.

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

bool isVowel(const char symbol)
{
    return (string("aeiou").find(tolower(symbol)) != string::npos);
}

bool containsVowel(const string text)
{
    return ((text.length() > 0) && (isVowel(text[0]) || containsVowel(text.substr(1))));
}

int main()
{
    // Stuff with containsVowel..
    return 0;
}
public boolean containsVowel ( String a)
{
if  (a.length() == 0)
    return false;

if ((a.charAt(a.length()-1)==('a'))||
      ((a.charAt(a.length()-1)==('e'))||
        ((a.charAt(a.length()-1)==('i'))||
            ((a.charAt(a.length()-1)==('o'))||
                ((a.charAt(a.length()-1)==('u')))))))
                    return true;
if ((a.charAt(a.length()-1)==('A'))||
      ((a.charAt(a.length()-1)==('E'))||
        ((a.charAt(a.length()-1)==('I'))||
            ((a.charAt(a.length()-1)==('O'))||
                ((a.charAt(a.length()-1)==('U')))))))
                    return true;
else 
 return containsVowel(a.substring(0, a.length()-1));
}

Thanks everybody for extensive explanations - been very very helpful.
i ended up submitting the following code:

    bool containsVowel (string s) {
        bool hasVowel=false;
        if (s.length()==0) return false;
        else if (s[0]=='a'||
                    s[0]=='e'||
                    s[0]=='u'||
                    s[0]=='o'||
                    s[0]=='i'||
                    s[0]=='A'||
                    s[0]=='E'||
                    s[0]=='U'||
                    s[0]=='O'||
                    s[0]=='I') 
            hasVowel=true;
        else
            hasVowel=containsVowel(s.substr(1,s.length()-1));
        return hasVowel;
    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.