我想在不使用外部库的情况下替换一些单词。 我的第一次尝试是复制字符串,但效率不高,所以这是我使用地址的另一种尝试:
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 :(得分: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条目而不是传递的参数)。