0

I want to make a recursive function that determines if a string's characters all consist of alphabets or not. I just can't figure it out. Here's what I've done so far but it doesn't work properly.

bool isAlphabetic(string s){
const char *c = s.c_str();
if ((!isalpha(c[0]))||(!isalpha(c[s.size()])))
{
    return false;
}
else if (isalpha(c[0]))
{
    isAlphabetic(c+1);
    return true;
}
}

can anyone suggest a correct way?

5
  • "but it doesn't work properly" how does it not work? wrong result? crashes? Commented Dec 12, 2014 at 19:31
  • it returns false in every test case Commented Dec 12, 2014 at 19:32
  • Why do you need recursion for this in 1st place? Doesn't a simple for() loop fit, to solve the problem? Commented Dec 12, 2014 at 19:33
  • 2
    !isalpha(c[s.size()]) makes no sense; why are you testing if the null terminator is an alphanumeric character? (Hint: it's never an alphanumeric character.) Also, you need to return isAlphabetic(c+1); instead of calling it and then returning true; you're just ignoring the result of the recursive call. Commented Dec 12, 2014 at 19:33
  • @Joey12 Have you stepped through with a debugger to see whats going on? (Hint see cdhowie's comment) Commented Dec 12, 2014 at 19:34

3 Answers 3

2

Leaving aside the many partial strings you'll create (consider passing in just the string and a starting index instead), the isalpha(c[s.size()]) check will always fail, since that's the \0 at the end of the string. You're also ignoring the result of the recursive calls.

bool isAlphabetic(string s){
  if (s.size() < 1)
    return true;               // empty string contains no non-alphas

  const char *c = s.c_str();

  if (!isalpha(c[0]))
  {
    return false;              // found a non-alpha, we're done.
  }
  else
  {
    return isAlphabetic(c+1);  // good so far, try the rest of the string
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

What if you started with the empty string? I think that would break this. It needs and extra logic step to check for the empty string.
Just caught that. Thanks.
2

Building on Paul's answer, here is a fixed implementation that won't copy any portion of the string. It accomplishes this by passing a reference to the string object and an index to the character to check; recursion simply adds 1 to this index to check the next character, and so on until the end of the string is found.

I have removed your call to c_str() since it isn't needed. string can be directly indexed.

bool isAlphabetic(string const & s, int startIndex = 0) {
    // Terminating case: End of string reached. This means success.
    if (startIndex == s.size()) {
        return true;
    }

    // Failure case: Found a non-alphabetic character.
    if (!isalpha(s[startIndex])) {
        return false;
    }

    // Recursive case: This character is alphabetic, so check the rest of the string.
    return isAlphabetic(s, startIndex + 1);
}

Note that the empty string is considered alphabetic by this function. You can change this by changing return true to return !s.empty().

2 Comments

You could return false for empty strings by changing return true to return !s.empty() ... though returning true is probably better, with the meaning of isAlphabetic being "for all c in s, c is alpha", which is true of the empty set.
@JimBalter Indeed, that's not a bad option if that is the desired behavior. Added this to my answer.
0

Here a working example:

#include <iostream>
#include <string>

using namespace std;

bool isAlphabetic(string s)
{
    if( s.empty() )
    {
        return false;
    }

    cout << "checking: " << s[0] << endl;

    if( isalpha(s[0]) )
    {
        return true;
    }

    return isAlphabetic(&s[0]+1);
}

int main()
{
    string word0 = "test";
    if( isAlphabetic(word0) )
    {
        cout << word0 << " is alphabetic" << endl; 
    }
    else
    {
        cout << word0 << " is NOT alphabetic" << endl; 
    }

    string word1 = "1234";
    if( isAlphabetic(word1) )
    {
        cout << word1 << " is alphabetic" << endl; 
    }
    else
    {
        cout << word1 << " is NOT alphabetic" << endl; 
    }

    string word2 = "1234w";
    if( isAlphabetic(word2) )
    {
        cout << word2 << " is alphabetic" << endl; 
    }
    else
    {
        cout << word2 << " is NOT alphabetic" << endl; 
    }

   return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.