简体   繁体   中英

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

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.

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).

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.

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 :

#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));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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