我一直在读“C ++ For Everyone”一书,其中一个练习据说写了一个函数string reverse(string str)
,其中返回值与str
相反。
有人可以写一些基本代码并向我解释一下吗?从昨天开始我就一直盯着这个问题而无法理解。我得到的最远的是函数返回str
的第一个字母(我仍然不知道它是怎么发生的)
这是我得到的(发布此问题后一小时):
string reverse(string str)
{
string word = "";
if (str.length() <= 1)
{
return str;
}
else
{
string str_copy = str;
int n = str_copy.length() - 1;
string last_letter = str_copy.substr(n, 1);
str_copy = str_copy.substr(0, n);
word += reverse(str_copy);
return str_copy;
}
return word;
}
如果我输入“Wolf”,它将返回Wol。有人帮帮我
如果我return word
而不是return str_copy
,那么我会得到w
如果我return last_letter
,那么我会得到l
答案 0 :(得分:19)
我有两分钟,所以我会解释递归算法本身。以“输入”为例,它应该产生“tupni”。您可以通过
递归反转字符串答案 1 :(得分:7)
试试这个
string reverse(string &s)
{
if( s.length() == 0 ) // end condtion to stop recursion
return "";
string last(1,s[s.length()-1]); // create string with last character
string reversed = reverse(s.substr(0,s.length()-1));
return last+reversed; // Make he last character first
}
递归函数必须具有以下属性
这个递归函数基本上创建了一个最后一个字符的字符串,然后再次使用除最后一个字符之外的其余字符串调用自身。实际切换发生在返回last + reversed的最后一行。如果反过来会发生任何事情。 这是非常低效的,但它可以显示这个概念。
此致, Alois Kraus
答案 2 :(得分:6)
只是建议一种更好的处理递归的方法:
在C ++中使用递归进行字符串反转:
#include <iostream>
#include <string>
using namespace std;
string reverseStringRecursively(string str){
if (str.length() == 1) {
return str;
}else{
return reverseStringRecursively(str.substr(1,str.length())) + str.at(0);
}
}
int main()
{
string str;
cout<<"Enter the string to reverse : ";
cin>>str;
cout<<"The reversed string is : "<<reverseStringRecursively(str);
return 0;
}
答案 3 :(得分:2)
我不会为你写一个完整的算法,但这里有一个提示:
如何交换两个最外面的字符,然后将它们应用到中间的字符?
哦,如果那本书真的提出string reverse(string str)
作为适当的功能签名,请将其丢弃并改为购买good book。
答案 4 :(得分:2)
这是我的反转输入字符串的递归函数版本:
void reverse(char *s, size_t len)
{
if ( len <= 1 || !s )
{
return;
}
std::swap(s[0], s[len-1]);// swap first and last simbols
s++; // move pointer to the following char
reverse(s, len-2); // shorten len of string
}
答案 5 :(得分:1)
最短,最简单
class Solution {
public:
string reverseString(string s) {
string str;
if(s != "\0"){
str = reverseString(s.substr(1, s.length()));
str += s.substr(0,1);
}
return str;
}
};
答案 6 :(得分:0)
字符串可以就地反转。如果我们从最小的字符串(即一个字符串)开始,则无需执行任何操作。这是我们停止或从递归调用返回的地方,它成为我们的基本情况。
接下来,我们必须考虑一种交换最小字符串(即两个或更多字符)的通用方法。最简单的逻辑是将当前字符str[current_index]
换成str[str_length-1 - current_index]
另一侧的字符。
最后,再次调用反向函数以获取下一个索引。
#include <iostream>
using namespace std;
void reverse_string(std::string& str, int index, int length) {
// Base case: if its a single element, no need to swap
// stop swapping as soon as we reach the mid, hence index*2
// otherwise we will reverse the already reversed string
if( (length - index*2) <= 1 ) {
return;
}
// Reverse logic and recursion:
// swap current and opposite index
std::swap(str[index], str[length-1 - index]);
// do the same for next character (index+1)
reverse_string(str, index+1, length);
}
int main() {
std::string s = "World";
reverse_string(s, 0, s.length());
std::cout << s << endl;
}
答案 7 :(得分:0)
我做了类似的事情,它做了逆转。我从字符串的两个极端到字符串的中心处取两个变量遍历字符串,当它们重叠或相等时,则反转终止。
举个例子:输入'a'
并将函数调用为
'd'
以递归方式递增/递减变量指针。
首先,指针指向'b'
和'c'
并交换它们,然后它们指向i >= j
和string ReverseString(string& str,int i,int j){
if(str.length() < 1 || str == "" || i >= j){
return "";
}
else{
char temp = str[i];
str[i] = str[j];
str[j] = temp;
ReverseString(str,i+1,j-1);
}
return str;
}
并交换它们。最终var friends = [{ friend_id: 3, friend_name: 'Jim' }, { friend_id: 14, friend_name: 'Selma' }];
_.remove(friends, friend => friend.friend_id === 14);
console.log(friends);
调用基本情况为真,因此递归终止。这个问题的主要内容是传递输入字符串作为参考。
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>
答案 8 :(得分:0)
你可以实现自己的反向,类似于std :: reverse。
template <typename BidirIt>
void reverse(BidirIt first, BidirIt last)
{
if((first == last) || (first == --last))
return;
std::iter_swap(first, last);
reverse(++first, last);
}
答案 9 :(得分:0)
所有现有的解决方案都有太多的代码,并没有真正做任何事情,因此,我的理解是:
#include <iostream>
#include <string>
std::string
r(std::string s)
{
if (s.empty())
return s;
return r(s.substr(1)) + s[0];
}
int
main()
{
std::cout << r("testing") << std::endl;
}
P.S。我偶然发现了这个问题,试图为std::string
找到C s+1
中char *
的C {s.substr(1, s.length()-1)
。没有走std::string::npos
的整个路线,看起来太难看了。事实证明,有s.substr(1)
,这意味着直到字符串结束,并且它已经是第二个参数的默认值,因此,s + 1
就足够了(加上,它也看起来效率更高,与C中的简单return
相同。
但是,请注意,除非编译器能够执行所谓的尾递归优化,否则递归通常不会随着输入的增大而缩放。 (在命令式语言中很少依赖递归。)
但是,为了使尾递归优化被激活,通常要求(0)递归仅在+ s[0]
语句中发生,并且,(1),没有进一步的操作是使用父函数中的递归回调结果执行。
例如,在上面的情况中,s[s.length()-1] +
在子调用完成后由父项逻辑完成(即使你去了更加丑陋的clang++ -O3
路由,它也可能是这样),所以,它也可以防止大多数编译器进行尾递归优化,从而使得函数在大输入上效率非常低(如果由于堆耗尽而没有完全破坏)。
(对于它的价值,我已经尝试编写了一个更符合尾递归的解决方案(确保通过函数本身的参数增加返回结果),但是反汇编结果二进制似乎表明它比C ++这样的命令式语言更复杂,请参阅gcc: is there no tail recursion if I return std::string in C++?。)
答案 10 :(得分:0)
1行递归解决方案:
string RecursiveReverse(string str, string prev = "") {
return (str.length() == 0 ? prev : RecursiveReverse(str.substr(0, str.length()-1), prev += str[str.length()-1]));
}
你这样称呼它:
cout << RecursiveReverse("String to Reverse");
答案 11 :(得分:0)
我知道我不应该给出解决方案,但由于没有人提到这个简单的解决方案,我应该分享它。我认为代码字面上是算法,因此不需要伪代码。
void c_plusplus_recursive_swap_reverse(std::string::iterator start,
std::string::iterator end)
{
if(start >= end) {
return;
}
std::iter_swap(start, end);
c_plusplus_recursive_swap_reverse(++start, --end);
}
要使用它:
c_plusplus_recursive_swap_reverse(temp.begin(), temp.end());
答案 12 :(得分:-1)
void ClassName::strgRevese(char *str)
{
if (*str=='\0')
return;
else
strgRevese(str+1);
cout <<*str;
}
答案 13 :(得分:-1)
这是我的3行反向字符串
std::string stringRevers(std::string s)
{
if(s.length()<=1)return s;
string word=s.at(s.length()-1)+stringRevers(s.substr(0,s.length()-1));//copy the last one at the beginning and do the same with the rest
return word;
}
答案 14 :(得分:-1)
void reverse(string &s, int &m) {
if (m == s.size()-1)
return;
int going_to = s.size() - 1 - m;
string leader = s.substr(1,going_to);
string rest = s.substr(going_to+1,s.size());
s = leader + s.substr(0,1) + rest;
reverse(s,++m);
}
int main ()
{
string y = "oprah";
int sz = 0;
reverse(y,sz);
cout << y << endl;
return 0;
}
答案 15 :(得分:-1)
已经有一些很好的答案,但我想用完整的Recursive reverseing string添加我的方法。
#include <iostream>
#include <string>
using namespace std;
char * reverse_s(char *, char*, int,int);
int main(int argc, char** argv) {
if(argc != 2) {
cout << "\n ERROR! Input String";
cout << "\n\t " << argv[0] << "STRING" << endl;
return 1;
}
char* str = new char[strlen(argv[1])+1];
strcpy(str,argv[1]);
char* rev_str = new char[strlen(str)+1];
cout<<"\n\nFinal Reverse of '" << str << "' is --> "<< reverse_s(str, rev_str, 0, strlen(str)) << endl;
cin.ignore();
delete rev_str, str;
return 0;
}
char* reverse_s(char* str, char* rev_str, int str_index, int rev_index ) {
if(strlen(str) == 1)
return str;
if(str[str_index] == '\0' ) {
rev_str[str_index] = '\0';
return rev_str;
}
str_index += 1;
rev_index -=1;
rev_str = reverse_s(str, rev_str, str_index, rev_index);
if(rev_index >= 0) {
cout << "\n Now the str value is " << str[str_index-1] << " -- Index " << str_in
dex << " Rev Index: " << rev_index;
rev_str[rev_index] = str[str_index-1];
cout << "\nReversed Value: " << rev_str << endl;
}
return rev_str;
}
答案 16 :(得分:-2)
它将递归地反转原始字符串
void swap(string &str1, string &str2)
{
string temp = str1;
str1 = str2;
str2 = str1;
}
void ReverseOriginalString(string &str, int p, int sizeOfStr)
{
static int i = 0;
if (p == sizeOfStr)
return;
ReverseOriginalString(str, s + 1, sizeOfStr);
if (i <= p)
swap(&str[i++], &str[p])
}
int main()
{
string st = "Rizwan Haider";
ReverseOriginalString(st, 0, st.length());
std::cout << "Original String is Reversed: " << st << std::endl;
return 0;
}
答案 17 :(得分:-2)
问题是写一个递归函数。这是一种方法。不是一个简洁的代码,但做了所需的。
/* string reversal through recursion */
#include <stdio.h>
#include <string.h>
#define size 1000
char rev(char []);
char new_line[size];
int j = 0;
int i =0;
int main ()
{
char string[]="Game On";
rev(string);
printf("Reversed rev string is %s\n",new_line);
return 0;
}
char rev(char line[])
{
while(line[i]!='\0')
{
i++;
rev(line);
i--;
new_line[j] = line[i];
j++;
return line[i];
}
return line[i];
}