2014-12-12 2 views
0

Я хочу сделать рекурсивную функцию, которая определяет, все ли символы строки состоят из алфавитов или нет. Я просто не могу понять. Вот что я сделал до сих пор, но это не работает должным образом.Как вернуть определенное логическое значение в рекурсивную функцию?

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; 
} 
} 

Может ли кто-нибудь предложить правильный путь?

+0

«но он не работает должным образом», как она не работает? неправильный результат? аварии? – Borgleader

+0

он возвращает false в каждом случае – Joey12

+0

Зачем вам нужна рекурсия для этого на 1-м месте? Не подходит ли простой цикл 'for()' для решения проблемы? –

ответ

2

Оставляя в стороне множество частичных строк, которые вы создадите (подумайте о передаче только строки и начального индекса), проверка isalpha(c[s.size()]) всегда будет терпеть неудачу, так как это \0 в конце строки. Вы также игнорируете результат рекурсивных вызовов.

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 
    } 
} 
+0

Что делать, если вы начали с пустой строки? Я думаю, что это нарушит это. Для этого требуется и дополнительный логический шаг для проверки пустой строки. – Giffyguy

+0

Только что понял. Благодарю. –

2

Опираясь на Paul's answer, здесь фиксируется реализация, которая не копирует какую-либо часть строки. Он выполняет это, передавая ссылку на объект string и указатель на проверяемый символ; рекурсия просто добавляет 1 к этому индексу для проверки следующего символа и так далее до тех пор, пока не будет найден конец строки.

Я удалил ваш звонок до c_str(), так как он не нужен. string могут быть непосредственно проиндексированы.

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); 
} 

Обратите внимание, что пустая строка считается этой буквой буквенно-цифровой. Вы можете изменить это, изменив return true на return !s.empty().

+0

Вы можете вернуть false для пустых строк, изменив 'return true' на' return! S.empty() '... хотя возвращение true, вероятно, лучше, со значением isAlphabetic being" для всех c в s, c является альфа ", что верно для пустого множества. –

+0

@JimBalter Действительно, это не плохой вариант, если это желаемое поведение. Добавил это к моему ответу. – cdhowie

0

Вот рабочий пример:

#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; 
} 
Смежные вопросы