问题是删除相邻的一对相同的字母表,直到没有这样的字母对。我已经使用了递归。但代码给出了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";
}
答案 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;
}