C ++递归函数中的分段错误

时间:2018-05-08 12:41:57

标签: c++ recursion segmentation-fault

问题是删除相邻的一对相同的字母表,直到没有这样的字母对。我已经使用了递归。但代码给出了Segmentation故障。这次递归出了什么问题?

#include<iostream>
#include<string>
using namespace std;
string super(string s)
{
        for(int i=0;i<s.length();i++)
        {
                if(s[i]==s[i+1])
                {
                        s.erase(s.begin()+i);
                        s.erase(s.begin()+i+1);
                        s=super(s);
                        cout<<s;
                        break;
                }
                if(i+1==s.length())
                        return s;
        }
        return s;
}
int main()
{
        string s;
        cin>>s;
        s=super(s);
        if(s.length()<0)
                cout<<s;
        else
                cout<<"Empty String";
}

3 个答案:

答案 0 :(得分:4)

您的条件检查无序,s[s.length()]根据定义会导致分段错误,因此您需要确保i+1小于s的长度才能尝试访问它

现在您正在访问s[i+1],然后检查是否i+1 < s.length()

答案 1 :(得分:0)

您的索引超出范围。 if i == s.length() - 1(这是最后一个字符 ()),那么你的[i + 1]将超出范围。

通常,逻辑也是有缺陷的,因为每次遇到匹配时都会从头开始重新启动操作。如果你有'abccba'我假设你想要'abcba',但你的代码会返回abca。 您的解决方案的时间复杂度不太理想。这可以在线性时间内完成。

在最后一行中你想要s.length()&gt; 0(或者您可以使用s.empty())。

答案 2 :(得分:0)

据我所知,人们讨厌代码中的评论,所以我会在答案的顶部重新考虑他们:

首先,在for cicle中,因为没有超出索引,你必须从1开始并且如果字符串的i-1和i位置相等则ceck。

其次,你可以简单地从i-1位置擦除到i + 1位置。

最后当你想要打印主要的刺痛时,如果弦的长度不是空的话,你必须要知道,长度不能是&lt; 0

最重要的是,只是在自己内部调用方法并不能使它成为一个递归解决方案&#34;,下面的代码是针对您的问题的迭代解决方案

#include<iostream>
#include<string>
using namespace std;
string super(string s){
        for(int i=1;i<s.length();i++)                                 // you start from 1 to doesn't go out of bound
                if (s[i-1]==s[i])
                        s.erase(s.begin() + (--i), s.begin() + i + 1);// you decrease i and erase from i decreased to i + 1
        return s;
}
int main(){
        string s;
        cin>>s;
        s = super(s);
        cout << ((s.length())? s : "Empty String");                    // the string is empty if the lenght is not 0, you have to change < with >
        return 0;
}

这是一个递归解决方案,你可以看到for循环的消失(使用循环没有错误,但使用它们很容易做错)

#include<iostream>
#include<string>
using namespace std;
string super(string s, int i){
    if (i < s.length()){
        if (s[i-1]==s[i]){
            s.erase(s.begin() + i - 1, s.begin() + i + 1);
            s = super(s, i);
        }
        else
            s = super(s, i + 1);
    }
    return s;
}
int main(){
    string s;
    cin>>s;
    s = super(s, 1);    //from input the size can't be 0 so give 1 is ok
    cout << ((s.length())? s : "Empty String");
    return 0;
}