2013-03-30 19 views
3

我想在不使用外部库的情况下替换某些单词。 我第一次尝试是使字符串的副本,但它是没有效率的,所以这是另一种尝试,我用地址:在不使用外部库的情况下替换字符串列表中的整个单词

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>;这对我来说非常方便。

我想用它来输入大量的单词。 (假设用一些无害的词替换许多不良词)

+0

不要对自己失望。对于你正在做的事情,这实际上比你想象的要干净得多,特别是对于只用C++做几个月的人来说。 – WhozCraig

回答

0

您可以创建一个类,说代用品:

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(它将使用映射条目而不是传递的参数)。

2

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

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

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

2

听起来好像你想用无害的字符串替换字符串中的所有“坏”字,但是你当前的实现是低效的,因为坏字的列表远大于输入字符串的长度(subject)。它是否正确?

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

void ReplaceString(std::string &subject, const std::map<std::string, std::string>& replace_map) 
{ 
    size_t startofword = 0, endofword = 0; 
    while(startofword < subject.size()) 
    { 
     size_t length = std::string::npos; 

     //get next word in string 
     endofword = subject.find_first_of(" ", startofword); 
     if(endofword != std::string::npos) 
     length = endofword-startofword; 

     std::string search = subject.substr(startofword, length); 

     //try to find this word in the map 
     if(replace_map.find(search) != replace_map.end()) 
     { 
     //if found, replace the word with a new word 
     subject.replace(startofword, length, replace_map[search]); 
     startofword += replace_map[search].length(); 
     } 
     else 
     { 
     startofword += length; 
     } 

    } 

} 
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; 
} 
相关问题