我正在尝试编写一个反转字符串的递归方法,如下所示。
void reverse(string s,int i,int l)
{
static int j;
while(i<l)
{
char ch=s[i];
cout<<ch<<endl;
reverse(s,i+1,l);
cout<<"after="<<ch<<endl;
s[j]=ch;
j++;
}
cout<<s<<endl;
s[j]=0;
}
但我的输出不正确。 "after="<<ch
始终打印字符串的最后一个字符。
函数的参数是s是std :: string,i是从0开始的索引,l是字符串的长度。
任何人都可以指出我做错事的地方。
答案 0 :(得分:5)
你可能已经发现了问题。
另一种方法,如果您不喜欢/想要迭代器或反向函数。
string revStr(string str){
if (str.length() <= 1) {
return str;
}else{
return revStr(str.substr(1,str.length()-1)) + str.at(0);
}
}
答案 1 :(得分:1)
不要在函数内部使用while()
循环。此外,如果您希望修改,则需要通过引用传递字符串。这是你的代码有一点改进:):
void reverse(string& s,int i,int l)
{
static int j = 0;
if (i < l)
{
char ch=s[i];
cout<<ch<<endl;
reverse(s,i+1,l);
cout<<"after="<<ch<<endl;
s[j]=ch;
j++;
}
cout<<s<<endl;
}
答案 2 :(得分:1)
您的实现中有几个错误,就像其他答案已经指出的那样,最大的一个是您按值传递字符串,因此您对原始字符串的副本进行了更改,其次是循环不会结束是因为你使用while循环来打破递归,但是你只是在递归调用reverse时递增“i”,这意味着在第一次反向调用“i”时不会递增,所以while会只在递归的最后一次调用时中断,但是当它从它返回时,它会在前一次调用中卡住,因为该范围中的“i”将永远不会大于“l”。可以通过更改if指令的while来轻松修复。然后您的代码将按预期工作。
但是,如果要向后打印字符串,则应使用字符串类中的反向迭代器以相反的顺序遍历它,然后只需打印字符:
for (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit)
cout << *rit;
如果您使用的是C ++和字符串类,则应该使用其强大的功能。
如果你只是在进行递归练习,我不太明白你想要完成什么,但是如果我使用递归向后写一个字符串,我会做这样的事情:
void reverse(string& s, int i = 0)
{
// Break the recursion.
if(i >= s.size())
return;
char ch = s[s.size() - (i + 1)];
cout<< ch << endl;
++i;
reverse(s, i);
}
答案 3 :(得分:0)
我认为你会有一个带有签名的递归例程更好运
string reverse(const string s);
并实施我在Q评论中描述的算法:
通过利用堆栈,并消除i和l参数,反转字符串s与取第一个字符并预先挂起最后一个字符串的子串(s.length-1)相同字符,直到你(递归地)获得长度为1个字符的字符串,这是字符串本身!