替换字符串列表中的整个单词而不使用外部库

时间:2013-03-30 05:51:48

标签: c++ string replace

我想在不使用外部库的情况下替换一些单词。 我的第一次尝试是复制字符串,但效率不高,所以这是我使用地址的另一种尝试:

void ReplaceString(std::string &subject, const std::string &search, const std::string &replace) 
{
    size_t position = 0;
    while ((position = subject.find(search, position)) != std::string::npos)    //if something messes up --> failure
    {
         subject.replace(position, search.length(), replace);
         position = position + replace.length();
    }
}

因为这也不是很有效,我想用另一件事,但我被卡住;我想使用replace_stuff(std::string & a);这样的函数,使用string.replace()string.find()(使用for循环或其他东西解析它)的单个参数,然后使用std::map <std::string,std::string>;对我来说非常方便。

我想将它用于大量输入词。 (假设用一些无害的词代替许多坏词)

4 个答案:

答案 0 :(得分:2)

您的问题的问题是标准库中缺少必要的组件。如果您想要一个有效的实现,您可能需要trie来进行有效的查找。写一个作为答案的一部分将是很多代码。

如果您使用std::map,或者如果您的环境中有C ++ 11可用std::unordered_map,则需要使用有关输入字符串和搜索替换对的其他信息。地图。然后,您将对字符串进行标记,并检查每个标记是否必须更换。使用指向输入字符串的位置是一个好主意,因为它避免了复制数据。这将我们带到:

效率取决于内存访问(读取和写入),因此不应修改输入字符串。通过从空字符串开始并通过附加输入中的片段来创建输出。检查输入的每个部分:如果是单词,检查是否需要更换或者是否未经修改将其附加到输出。如果它不是单词的一部分,则不加修改地附加它。

答案 1 :(得分:2)

听起来你想要用无害的单词替换字符串中的所有“坏”单词,但是你当前的实现是低效的,因为坏单词列表比输入字符串的长度大得多({{1} })。这是对的吗?

如果是这样,以下代码应该使它更有效。如您所见,我必须将地图作为参数传递,但如果您的函数将成为类的一部分,则不需要这样做。

subject

答案 2 :(得分:2)

我使用以下功能,希望它有所帮助:

//=============================================================================
//replaces each occurence of the phrase in sWhat with sReplacement
std::string& sReplaceAll(std::string& sS, const std::string& sWhat, const std::string& sReplacement)
{
    size_t pos = 0, fpos;
    while ((fpos = sS.find(sWhat, pos)) != std::string::npos)
    {
        sS.replace(fpos, sWhat.size(), sReplacement);
        pos = fpos + sReplacement.length();
    }
    return sS;
}

//=============================================================================
// replaces each single char from sCharList that is found within sS with entire sReplacement
std::string& sReplaceChars(std::string& sS, const std::string& sCharList, const std::string& sReplacement)
{
    size_t pos=0;
    while (pos < sS.length())
    {
        if (sCharList.find(sS.at(pos),0)!=std::string::npos) //pos is where a charlist-char was found
        {
            sS.replace(pos, 1, sReplacement);
            pos += sReplacement.length()-1;
        }
        pos++;  
    }
    return sS;
}

答案 3 :(得分:0)

你可以创建一个类,比如Replacer:

class Replacer 
{
  std::map<std::string,> replacement;

public:
  Replacer()
  {
     // init the map here
     replacement.insert ( std::pair<std::string,std::string>("C#","C++") );
     //...
  }
  void replace_stuff(std::string & a);
}

然后,replace_stuff定义与原始的ReplaceString非常相似(它将使用map条目而不是传递的参数)。