我正在尝试找出如何逐个删除字符串中的一个字符,以便获得每次只缺少一个字符的所有版本。这是我想让它工作的方式,但却没有成功。
for(int i = 0 ; i < s.length() ; i++){
tmp.erase(0, i);
std::cout << tmp << std::endl;
s.at(i)++;
}
显然,它对第一个字符串的操作是正确的,但是接下来的字符串都被删除了。 JON 的预期输出应该是 ON JN JO
最简单的方法是每次复制字符串,并修改副本:
for(std::string::size_type i = 0 ; i < s.size() ; i++){
auto tmp=copy;
tmp.erase(i, 1);
std::cout << tmp << std::endl;
}
为了正确性,索引变量应该是std::string::size_type
,这是length()
和size()
返回的内容(使用size_t
和size()
自然地成对)。
您的代码几乎正确,只是忽略了每次复制字符串,并且s.at(i)++
不应该出现在那里。
tmp
重置为原始字符串值,因此它会不断从tmp
中擦除更多字符,直到为空。for(std::string::size_type i = 0 ; i < s.length() ; i++){
std::string tmp = s;
tmp.erase(i, 1);
std::cout << tmp << std::endl;
}
使用迭代器和临时副本的解决方案:
#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';
}
}
不需要临时副本的解决方案,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';
}
}
输出:
bcdefg
acdefg
abdefg
abcefg
abcdfg
abcdeg
abcdef
试试这个简单而直接的方法:
while (TMP.size()) {
cout << TMP << '\n';
TMP.erase(0, 1);
}
#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;
}
}
这太不高效了。
只需复制而不包括最后一个字符,然后逐步迭代地用原始字符替换该副本的结尾即可。
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));
}
}
std::string::size_type
,可能是size_t
也可能不是。此外,tmp.erase(i)
将删除从指定索引到字符串末尾的所有字符。如果要删除单个字符,需要使用tmp.erase(i, 1)
或tmp.erase(tmp.begin()+i)
。 - Remy Lebeau