Reputation: 93
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
Upvotes: 8
Views: 37417
Reputation: 3
#include <iostream>
using namespace std;
int main()
{
string s;
cin>>s;
for(int i=0;i<s.length();i++)
{
string s1=s;
s1.erase(i,1);
cout<<s1;
}
}
Upvotes: 0
Reputation: 45654
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));
}
}
Upvotes: 0
Reputation: 8758
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
Upvotes: 2
Reputation: 1288
Try this one simple and straight:
while (TMP.size()) {
cout << TMP << '\n';
TMP.erase(0, 1);
}
Upvotes: 0
Reputation: 118310
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.
Upvotes: 9
Reputation: 595837
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;
}
Upvotes: 3