我正在编写一个程序,我想实现的一个特性是一个错误检查类型的东西,如果C++程序在程序中搜索,* 没有 * 找到匹配,它将返回最接近的匹配字符串。
我目前的设置如下所示:
help_data["invite"] = "**How to use?**\n `/invite` - *No other parameters* \n **Purpose** \n To generate an invite for Beyond!";
help_data["help"] = "**How to use?** \n `/help [command]` \n **Purpose** \n To generate an embed on how a specific command works, and its' syntax.";
std::string command = std::get<std::string>(event.get_parameter("command"));
std::transform(command.begin(), command.end(), command.begin(), ::tolower); //lowercase
if (help_data.find(command) == help_data.end()) {
// Not Found
event.reply(dpp::ir_channel_message_with_source, dpp::message().set_content("Unable to find help data for command `" + command + "`"));
}
else {
// Found
}
谢谢!
1条答案
按热度按时间wn9m85ua1#
正如@BasileStarynkevitch所建议的,可以实现Levenstein distance,它测量两个字符串之间的编辑距离(插入、删除、替换的次数),或者换句话说,两个字符串有多相似,Levenstein距离的值越接近0,相似的字符串越多。
刚才我用C++从头开始实现了这个距离计算,并展示了一个使用这个距离函数在给定的字符串中找到与查询字符串最接近的字符串的例子。
函数
Levenstein()
根据Wikipedia实现(链接见上),并且不是为了便于阅读和理解而优化的,只是为了教育目的。在生产代码中使用Memoization技术可以使它更快(缓存相同函数调用结果),因为正如您所看到的,对于较大的字符串,我的实现将相当慢,对于相同的两个字符串,它将执行大量冗余的相同函数调用。另一种加速计算的方法是使用Dynamic programming方法来缓存和重用数组中以前的结果。Try it online!
输出:
正如答案的第1部分所建议的,我决定使用Memoization技术实现Levenstein distance的优化版本,以便在数组中存储和重用相同的结果。
这个版本有点难理解,读起来也比较长,但是运行起来要快得多。
Try it online!
输出:
我使用200 most common English words比较了计时。
比较了第1部分和第2部分中的慢速和快速(带记忆)Levenstein实现。
对于5个字母的字符串,慢速版本比快速版本慢8倍,对于10个字母的字符串,慢5000倍,这是非常非常慢的。这种缓慢的发生仅仅是因为许多重复的纯递归性质。
所有计时均低于代码(微秒)。
此外,在这里我提供了完整的代码,没有测量。
Try it online!
计时的控制台输出: