使用C ++中的递归从字符串中删除所有辅音

时间:2018-07-27 19:11:27

标签: c++ recursion

我几乎是编程新手,我尝试学习C ++。这是我感觉碰壁的第一项任务。我尝试搜索,但是因为人们通常使用循环来解决问题,所以我什么也找不到。

我试图找到一种递归解决方案,以从字符串中删除所有辅音(我想我知道如何使用循环来解决它,但想扩展我的递归知识)。

#include <iostream>
#include <string>

using namespace std;

int i = 0;
string s("");

string del_cons(string z){
    if(i == (z.length()-1) ){
        s+= z.substr(i);
        return s;
    }
    else if(z[i] == 'a' || z[i] == 'e' || z[i] == 'i' || z[i] == 'o' || z[i] == 'u'){
        i++;
        s+= del_cons(z.substr(i));
        return s;
    }
    else{
        s+= z.substr(i,1); 
        i++;
        s+= del_cons(z.substr(i));
        return s;
    }
}


int main(){
    string x;
    getline(cin, x);

    cout << del_cons(x) << endl;

    return 0;
}

代码可以编译,但是当用字符串尝试它时,出现以下错误消息:

terminate called after throwing an instance of 'std::out_of_range'
what():  basic_string::substr: __pos (which is 3) > this->size() (which is 2)

Abgebrochen(Speicherabzug geschrieben)

在处理代码时,此行似乎是问题所在:

s+= del_cons(z.substr(i));

有人可以提示我我做错了什么吗?似乎我在滥用substr()函数,但是我不知道怎么做。非常感谢。

3 个答案:

答案 0 :(得分:1)

对不起,但我无法抗拒...如果充分发挥C ++的作用,它是一种美丽而强大的语言...

#include <string>
#include <iostream>
#include <algorithm>

int main()
{
    std::string s;
    std::getline( std::cin, s );
    s.erase(
        std::remove_if(
            s.begin(),
            s.end(),
            [](unsigned char x){
                return std::string( "aeiouAEIOU" ).find( x ) == std::string::npos;
            }
        ),
        s.end()
    );
    std::cout << s << std::endl;
}

答案 1 :(得分:1)

也无法抗拒

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

using namespace std::literals::string_literals;

std::string del_cons(std::string const & str)
{
    if (!str.size())
        return "";

    if (!std::isalpha(static_cast<unsigned char>(str[0])) ||
        "AEIOUaeiou"s.find(str[0]) != str.npos )
        return str.substr(0, 1) + del_cons(str.substr(1));

    return del_cons(str.substr(1));
}

int main()
{
    std::string input;
    std::getline(std::cin, input);
    std::cout << del_cons(input) << '\n';
}

答案 2 :(得分:1)

如果您只是想了解递归并“手工”做更多的事情,则可能更容易查看字符串中是否还存在辅音,可以使用z.find_first_of(consonants),其中consonants可能是由所有辅音组成的字符串。如果返回std::string::npos,则找不到辅音,您可以返回输入字符串(停止条件)。 否则,可以将辅音取出(您现在知道其位置),也许使用z.substr并在辅音之前和之后串联子字符串。然后,使用新字符串递归调用函数。

然后,您可以编写一个更通用的函数,该函数使用第二个字符串,其中包含要从字符串中删除的所有字符。

同样,这不是一种好的代码习惯,也是使用全局变量作为递归参数的代码的最大缺陷之一(例如,在函数中有两个递归调用时,您会怎么做?)。您还需要在功能完成或要多次调用时重置它们。就您而言,您使用必须从头开始处理的字符串来调用函数,但是i可能已经增加了。您希望将i作为参数来指示以哪个字母开头,或者甚至更好的是,更改函数的结构。当我递归地编写函数时,我通常会首先想到停止条件:在哪种情况下无须做(例如空字符串或没有辅音的字符串)?然后我想到在其他情况下该怎么办。