从字符串中删除括号的C++函数不能捕获它们 我在C++中写了一个函数来从一个字符串中删除括号,但是它并不是总是因为某些原因而完全地捕获它们。 string sanitize(string word) { int i = 0; while(i < word.size()) { if(word[i] == '(' || word[i] == ')') { word.erase(i,1); } i++; } return word; }
样本结果: 输入:388887 产出:388887从字符串中删除括号的C++函数不能捕获它们 我在C++中写了一个函数来从一个字符串中删除括号,但是它并不是总是因为某些原因而完全地捕获它们。 string sanitize(string word) { int i = 0; while(i < word.size()) { if(word[i] == '(' || word[i] == ')') { word.erase(i,1); } i++; } return word; },c++,C++,样本结果: 输入:388887 产出:388887 为什么会这样?我可以通过调用输出上的函数来绕过这个问题,这样就可以运行两次字符串,但这显然不是一个好的编程。谢谢 为什么不使用strtok和一个临时字符串呢 string sanitize(string word) { int i = 0; string rVal; char * temp; strtok(word.c_str(), "()"); //I make the assumption that your values should
为什么会这样?我可以通过调用输出上的函数来绕过这个问题,这样就可以运行两次字符串,但这显然不是一个好的编程。谢谢 为什么不使用strtok和一个临时字符串呢
string sanitize(string word)
{
int i = 0;
string rVal;
char * temp;
strtok(word.c_str(), "()"); //I make the assumption that your values should always start with a (
do
{
temp = strtok(0, "()");
if(temp == 0)
{
break;
}
else { rVal += temp;}
}while(1);
return rVal;
}
如果删除圆括号,则下一个字符将移动到该圆括号先前占用的索引,因此不会选中它。使用另一个
它失败了,因为您在所有情况下都在增加索引。只有在不删除字符的情况下才应该这样做,因为删除操作会将超出该点的所有字符向后移动一个 换句话说,如果要删除两个或多个连续字符,就会出现此问题。它不是同时删除它们,而是将两者合并为一 在函数中运行两次将对特定的输入字符串起作用,但您仍然会遇到类似pax的问题,因为第一次调用将它折叠到pax,第二次调用将为您提供pax 一种解决方案是在删除字符时不提前索引:
std::string sanitize (std::string word) {
int i = 0;
while (i < word.size()) {
if(word[i] == '(' || word[i] == ')') {
word.erase(i,1);
continue;
}
i++;
}
return word;
}
您可以在以下完整程序中看到这一点:
#include <iostream>
#include <string>
std::string sanitize (std::string word) {
int i = 0;
while ((i = word.find_first_of ("()", i)) != std::string::npos)
word.erase (i, 1);
return word;
}
int main (void) {
std::string s = "((3)8)8)8)8))7 ((((pax))))";
s = sanitize (s);
std::cout << s << '\n';
return 0;
}
如果编译器不支持lambdas,则可以将检查作为函数对象函子实现。由于未删除的元素只复制一次到最终位置,因此该算法具有线性复杂性。可行是可行的。就我个人而言,我更喜欢使用char*而不是std::string,大多数人觉得这很奇怪。如果我们想用纯C++方法,我确信有一百万种方法可以去做。另外,关于编程的最好部分:一百万种方法,回到家里。让我们从一个不编译的事实开始。“是的,@ MooingDuck,C++有Strutok,它在CSTRON头上。如果我要把所有的东西都给他,我会亲自给他发代码。如果人们想这样做,一个char*,或者一个dynamic_cast就可以解决问题。或者,如果我能为他解决整个问题,我会想出一个完全不同的解决方案。当然,你是对的。与重新发明轮子相比,我本可以按原样修复他的函数。c_str member函数返回一个const char*。修改字符串,就像这个糟糕的例子一样,是未定义的行为。如果你必须使用strtok,你必须先制作你自己的字符串副本。给任何未来的访问者的提示:word.erasestd::remove_ifstd::beginword,std::endword,[]char c{return c==| c==;},std::endword;应该就这么做了。@chris,这应该是回答,而不是评论。@paxdiablo,我想是的。我想已经有关于OP代码的好答案了,但我想我应该填补这个空白。@paxdiablo,我完全错过了David答案的附件,直到我发布之后。毕竟它就在那里:p我想上次之后,当它还不在那里的时候,我没有太仔细地看。这就成功了,我知道这很简单。谢谢
std::string sanitize (std::string word) {
int i = 0;
while (i < word.size()) {
if(word[i] == '(' || word[i] == ')') {
word.erase(i,1);
continue;
}
i++;
}
return word;
}
std::string sanitize (std::string word) {
int spos = 0;
while ((spos = word.find_first_of ("()", spos)) != std::string::npos)
word.erase (spos, 1);
return word;
}
#include <iostream>
#include <string>
std::string sanitize (std::string word) {
int i = 0;
while ((i = word.find_first_of ("()", i)) != std::string::npos)
word.erase (i, 1);
return word;
}
int main (void) {
std::string s = "((3)8)8)8)8))7 ((((pax))))";
s = sanitize (s);
std::cout << s << '\n';
return 0;
}
388887 pax
while(i < word.size())
{
if(word[i] == '(' || word[i] == ')')
{
word.erase(i,1);
}
i++;
}
while (i < word.size()) {
if (word[i] == '(' || word[i] == ')' ) {
word.erase(i,1);
} else {
++i;
}
}
s.erase( std::remove_if(s.begin(), s.end(),
[](char ch){ return ch==`(` || ch ==`)`; })
s.end() );