首页 > 解决方案 > 根据地图替换所有事件

问题描述

这个问题可能已经回答了,但我还没有找到。

假设我有一个std::map<string,string>包含<replace_all_this, to_this>的字符串对。

我检查了Boost 的格式库,它很接近但并不完美:

std::map<string,string> m;
m['$search1'] = 'replace1';
m['$search2'] = 'replace2';
format fmter1("let's try to %1% and %2%.");
fmter % 36; fmter % 77;
for(auto r : m) {
  fmter % r.second;
}
// would print "let's try to replace1 and replace2

这会起作用,但我无法控制什么。实际上我想得到这个结果:

format fmter1("let's try to $search2 and $search1 even if their order is different in the map.");
...
//print: "let's try to replace2 and replace1 even if their order is different in the map".

请注意:地图可以包含更多项目,并且项目可以在格式化程序中出现多次。

2020 年的方法是什么,我希望它既有效又快速,所以我会避免多次迭代地图。

标签: c++

解决方案


可能有新的库,但没有新的算法比我们目前拥有的更快。

假设您的格式意味着$<name>您的变量,您可以搜索第一个'$',阅读<name>地图中的搜索,然后进行替换。这使您可以跳过替换或也对其进行处理(即在变量可以引用另一个变量的情况下使其递归)。

我不认为反过来做会更快:即浏览地图并搜索字符串中的名称意味着您将多次解析字符串,如果您有很多变量,它将是如果大多数都不可能是您的字符串的一部分,那将是巨大的浪费。此外,如果您想防止某种程度的递归,这非常复杂。

您最终可以优化的地方是计算结果字符串的大小并分配一次缓冲区,而不是使用+=不太可能会变慢的缓冲区。

我的snaplogger中有这样的实现。变量必须在括号之间,并且可以包含多个参数以进一步调整数据。这里有关于该功能支持什么的文档,并且按照书面说明,您可以轻松地扩展该类以添加更多功能。它可能与您正在寻找的内容不是一对一的匹配,但它向您表明没有 20 种实现该功能的方法。


推荐阅读