C ++字符串操作对我来说没有意义

时间:2010-04-25 17:43:31

标签: c++ string programming-languages

这个特定的赋值与从字符串中删除子串有关;我正在网上尝试一些斯坦福SEE课程来学习一些新语言。

到目前为止,我已经得到了以下内容,但是如果text = "hello hello"remove ="el",它会陷入循环,但是如果我将文字更改为text = "hello hllo",它会有效,我觉得我做的事情显然很愚蠢。

分配中有一条规定,即不修改传入的字符串,而是返回一个新的字符串。

string CensorString1(string text, string remove){
    string returned;
    size_t found=0, lastfound=0;
    found = (text.substr(lastfound,text.size())).find(remove);
    while (string::npos != found ){
        returned += text.substr(lastfound,found);
        lastfound = found + remove.size();
        found = (text.substr(lastfound,text.size())).find(remove);
    }
    returned += text.substr(lastfound,found);
    return returned;
}

指导将不胜感激:-)谢谢

更新

给出了非常友好的建议并将我的代码修改为:

string CensorString1(string text, string remove){
string returned;
size_t found=0, lastfound=0;
found = text.find(remove);
while (string::npos != found ){
    returned += text.substr(lastfound,found);
    lastfound = found + remove.length();
    found = text.find(remove,lastfound);
}
returned += text.substr(lastfound);
return returned;
}

但仍然表现相同

还有更多想法吗?

3 个答案:

答案 0 :(得分:5)

found = (text.substr(lastfound,text.size())).find(remove);不正确。它返回text.substr(lastfound,text.size())中搜索到的字符串的索引,但不返回text

您应该将其更改为found = text.find(text, lastfound);

除了不正确之外,取一个子字符串(这意味着,分配一个新字符串)并在其中计算索引是非常低效的,除非优化器是超级智能的。

此外,最终的returned += text.substr(lastfound,found);也是不正确的:您需要添加文本的最后一个块,而不是found索引之前的那个(很可能是空的,lastfound可以小于found。最好是returned += text.substr(lastfound);

编辑:
在第二个示例中,您需要将returned += text.substr(lastfound,found); 替换为returned += text.substr(lastfound,found-lastfound);substr的第二个参数是长度,而不是位置。

通过此更改,测试示例在我的测试程序中正常运行。

(J.F. Sebastian补充道:)

string CensorString1(string const& text, string const& remove){
  string returned;
  size_t found = string::npos, lastfound = 0;
  do {
    found = text.find(remove, lastfound);
    returned += text.substr(lastfound, found-lastfound);
    lastfound = found + remove.size();
  } while(found != string::npos);
  return returned;
}

答案 1 :(得分:0)

text.substr(lastfound,text.size())text中间的某处开始,并继续text的整个大小。这没有意义,虽然我认为它的工作原理是因为这些特定函数处理范围错误的方式不稳定。 string::npos会比size更好地表明您的意图。

一般来说,string的操纵成员不如<algorithm>中更通用的算法优雅。我建议你改用std::search,而不是string::iterator来代替整数偏移。

更新:第二个示例中存在相同类型的错误。使用string::npos作为substr的第二个参数,以获得到最后的子字符串。

答案 2 :(得分:0)

found = (text.substr(lastfound,text.size())).find(remove);从零开始重新计算find()函数(即最后一个匹配后的第一个字符将具有索引0,它看起来像text的开头)。但是,find可以采用2个参数,其中第二个参数是要从中开始的索引。因此,您可以将此行更改为found = text.find(remove,lastfound)

更清楚:

text =                      hellohello
find "el" in here            ^ is at index 1 in `text`
substring after match          lohello
find "el" in here                 ^ is at index 3 in the substring
                                    but your program doesn't know
                                    that's actually index 6 in `text`