C++ 在不使用外部库的情况下替换字符串列表中的整个单词
我想在不使用外部库的情况下替换一些单词。 我的第一次尝试是复制字符串,但效率不高,因此这是我使用地址的另一次尝试:C++ 在不使用外部库的情况下替换字符串列表中的整个单词,c++,string,replace,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)) !
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::map
,或者如果您的环境中有可用的C++11,则使用std::unordered_map
,则需要利用有关输入字符串和映射中的搜索替换对的其他信息。然后将字符串标记化,并检查每个标记是否需要替换。使用指向输入字符串的位置是一个好主意,因为它可以避免复制数据。这让我们想到:
效率将取决于内存访问(读写),因此不应修改输入字符串。通过从空字符串开始并从输入中附加片段来创建输出。检查输入的每一部分:如果它是一个单词,请检查它是否需要替换,或者它是否未经修改附加到输出中。如果它不是单词的一部分,请不加修改地附加它。听起来您想用无害的单词替换字符串中的所有“坏”单词,但您当前的实现效率很低,因为坏单词的列表远远大于输入字符串的长度(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;
}
}
}
void ReplaceString(std::string和subject,const std::map和replace_map)
{
大小\u t开始字=0,结束字=0;
while(startofword
我使用以下功能,希望对您有所帮助:
//=============================================================================
//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;
}
//=============================================================================
//将sWhat中出现的每个短语替换为sReplacement
std::string&sReplaceAll(std::string&sS,const std::string&sWhat,const std::string&sReplacement)
{
尺寸\u t位置=0,FPO;
while((fpos=sS.find(sWhat,pos))!=std::string::npos)
{
替换(fpos、sWhat.size()、sReplacement);
pos=fpos+sReplacement.length();
}
返回sS;
}
//=============================================================================
//将sS中找到的sCharList中的每个字符替换为整个sReplacement
std::string&sReplaceChars(std::string&sS,const std::string&sCharList,const std::string&sReplacement)
{
大小\u t pos=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);
}
类替换程序
{
地图替换;
公众:
替换者()
{
//在这里初始化地图
replacement.insert(std::pair(“C#“,“C++”);
//...
}
void replace_stuff(std::string&a);
}
然后,replace_stuff定义将与原始ReplaceString非常相似(它将使用映射条目而不是传递的参数)。不要自寻烦恼。对于你所做的,这实际上比5月1日你想的要干净很多,尤其是对于那些只在C++中做了几个月的人。