简体   繁体   English

如何一次从字符串中删除一个字符?

[英]How do I delete one character from a string at a time?

I am trying to figure out how to delete one character at a time from a string, so that I can obtain all versions of the string with only one character missing at a time. 我试图弄清楚如何从字符串中一次删除一个字符,这样我就可以获得所有版本的字符串,一次只丢失一个字符。 This is what I am trying to make work, but to no avail. 这就是我想要做的工作,但无济于事。

for(int i = 0 ; i < s.length() ; i++){
    tmp.erase(0, i);
    std::cout << tmp << std::endl;
    s.at(i)++;
}

It obviously works correctly for the first one, but then deletes the rest. 它显然适用于第一个,但随后删除其余的。 JON should have an expected output of ON JN JO JON应该具有ON JN JO的预期输出

You are not resetting tmp to the original string value on each loop iteration, so it keeps erasing more and more characters from tmp until it is empty. 您没有在每次循环迭代时将tmp重置为原始字符串值,因此它会一直从tmp删除越来越多的字符,直到它为空。

You are also removing the wrong range of characters on each loop iteration. 您还在每次循环迭代中删除了错误的字符范围。

You are also modifying the original string on each loop iteration to increment the value of its individual characters. 您还在每次循环迭代时修改原始字符串以增加其各个字符的值。 Why are you doing that at all? 你为什么要那样做?

Try something more like this instead: 尝试更像这样的东西:

for(std::string::size_type i = 0 ; i < s.length() ; i++){
    std::string tmp = s;
    tmp.erase(i, 1);
    std::cout << tmp << std::endl;
}

The easiest way is to make a copy of the string each time, and modify the copy: 最简单的方法是每次都复制一个字符串,然后修改副本:

for(std::string::size_type i = 0 ; i < s.size() ; i++){
    auto tmp=copy;
    tmp.erase(i, 1);
    std::cout << tmp << std::endl;
}

For correctness, the index variable should be a std::string::size_type , what both length() and size() return (with size_t and size() naturally belonging together). 为了正确,索引变量应该是std::string::size_typelength()size()返回( size_tsize()自然归属于一起)。

Your code almost got it right, except that it neglected to make the copy of the string each time, and s.at(i)++ didn't belong there. 你的代码几乎是正确的,除了它每次都忽略了复制字符串,而s.at(i)++不属于那里。

Try this one simple and straight: 试试这个简单直接:

while (TMP.size()) {
    cout << TMP << '\n';
    TMP.erase(0, 1);
}

Solution with iterators and temp copies: 使用迭代器和临时副本的解决方案:

#include <iostream>
#include <string>
int main()
{
    std::string s("abcdefg");
    for (auto i = s.begin(); i != s.end(); ++i)
    {
        const std::string b = { s.begin(), i }; // temp copy!
        const std::string e = { i + 1, s.end() }; // temp copy!
        std::cout << b << e << '\n';
    }
}

A solution without temporary copies, C++20 std::string_view : 没有临时副本的解决方案,C ++ 20 std::string_view

#include <iostream>
#include <string>
#include <string_view>
int main()
{
    std::string s("abcdefg");
    for (auto i = s.begin(); i != s.end(); ++i)
    {
        const std::string_view b = { s.begin(), i };
        const std::string_view e = { i + 1, s.end() };
        std::cout << b << e << '\n';
    }
}

Output: 输出:

bcdefg
acdefg
abdefg
abcefg
abcdfg
abcdeg
abcdef

That's all damn inefficient. 这一切都非常低效。

Just make a copy without the last character, and then slowly, iteration by iteration, replace the end of that copy with characters from the original. 只需复制一个没有最后一个字符的副本,然后慢慢地迭代迭代,用原始字符替换该副本的结尾。

template <class F>
void do_with_one_missing(std::string_view s, F f) {
    auto i = size(s);
    if (i-- > 0) return;
    std::string x = s.remove_suffix(1);
    f(std::as_const(x));
    while (i-- > 0) {
        x[i] = x[i + 1];
        f(std::as_const(x));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM