使用带递归的传递指针从字符串中删除 X

removing x from a string using pass by pointer with recursion

提问人:parasguglani 提问时间:6/3/2022 更新时间:6/3/2022 访问量:126

问:

我编写此代码是为了使用递归从字符串中删除所有出现的 x

#include <bits/stdc++.h>
using namespace std;
void removex(string str)
{
    if (str.length()==0)
    {
        return;
    }
    if (str[0] != 'x')
    {
         removex(str.substr(1,str.length()));
    }
    int i = 1;
    for (; str[i] != '\0'; i++)
    {
        str[i-1]=str[i];
    }
    str[i - 1] = str[i];
     removex(str);
    //  cout<<"strq"<<str<<endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        string str;
        cin >> str;
        removex(str);
        cout << str << endl;
    }
    return 0;
} 

但是它是按值传递的,如果我尝试使用按引用传递,它会给出一个错误 对 non-const 的引用的初始值必须是 lvalueC。这意味着我需要使引用常量不适合代码的其余部分。我尝试通过指针并使用箭头运算符,但是无法获取索引处的值,并且不确定如何进行递归调用。传递地址还是 ponter?有人可以相应地修改它吗?

C++ 字符串 递归 按引用传递

评论

1赞 user4581301 6/3/2022
通常,当我递归容器时,我发现传递开始和结束迭代器对于消除不必要的副本非常有帮助。我根本不会使用。我会在现有字符串中传递我希望下一个递归查看的范围。相对较新的也非常有帮助。substrstd::string_view
0赞 user4581301 6/3/2022
问题是 substr 返回一个临时变量。除非你为非临时的东西分配一个临时的,否则它们不会持续足够长的时间,以至于对它们的引用没有价值。你可以通过制作它来强制临时性地坚持下去,但这违背了重点。不能替换字符串中的 xs。constconst
0赞 Goswin von Brederlow 6/3/2022
即使你的代码可以工作,生成的字符串仍然具有原始长度,最后重复内容。您需要使用来缩短字符串。str.erase(...)

答:

1赞 Alexis 6/3/2022 #1

鉴于您使用的是 C++,我将使用标准库的功能。我相信这个问题可以很容易地用一行代码来解决。假设字符串变量名为 line,您只需要执行如下操作:

line.erase(remove(line.begin(), line.end(), 'x'), line.end());

下面是一个完整的示例:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
  std::string line = "12djd V x jhrf h58HSFH HUHFuhfdhkdh   uhdfvygh 234 fhj xxx";
  std::cout << "Line before removing the x character: " << line << std::endl;
  line.erase(remove(line.begin(), line.end(), 'x'), line.end());
  std::cout << "Line after removing the x character:  " << line << std::endl;
  return 0;
}

上面的示例将产生以下输出:

Line before removing the x character: 12djd V x jhrf h58HSFH HUHFuhfdhkdh   uhdfvygh 234 fhj xxx
Line after removing the x character:  12djd V  jhrf h58HSFH HUHFuhfdhkdh   uhdfvygh 234 fhj 

此处提供了可以运行的示例:https://onlinegdb.com/4wzMXTXP5

1赞 WhozCraig 6/3/2022 #2

用递归和递归来做这件事是精神错乱的一个可怕的模板。擦除/删除习语就是为了这个目的而存在的,它以迭代方式运行,并且非常高效。最重要的是,它已经存在;您所要做的就是设置通话。std::string

也就是说,如果你一心想以递归方式(而且效率低下)来做这件事,你需要以某种方式将结果传达给调用者(包括递归调用)。下面使用函数返回类型(即 .这也使用全局自由,它允许串联 + 以返回一个新字符串:std::stringoperator +charstd::string

#include <iostream>
#include <string>

std::string removex(std::string str)
{
    if (!str.empty())
    {
        if (str[0] == 'x')
            str = removex(str.substr(1));
        else
            str = str[0] + removex(str.substr(1));
    }
    return str;
}

int main()
{
    std::string str = "Remove all x chars from this string.";
    std::cout << "Before: " << str << '\n';
    std::cout << "After:  " << removex(str) << '\n';
    return 0;
} 

输出

Before: Remove all x chars from this string.
After:  Remove all  chars from this string.

也就是说,这不是我这样做的方式。我会使用擦除/删除成语,这会更快,更省内存。