c++ - 计算在同一位置至少包含一个常见字符的不同字符串对
问题描述
有没有一种更有效的方法来计算数组中在同一位置至少有一个公共字符的不同字符串对。字符串的长度总是相同的 3。例如,
- " a bc", a cb": 计数
- “b un ”、“f un ”:计数
- “xyz”、“yzx”:不算数
- “一”、“二”:不算数
我尝试编写一个函数来检查它们是否匹配,然后使用 for 循环对其进行计数,但它似乎效率不高,尤其是当数组很大时。
bool match(std::string a, std::string b) {
for (int i = 0; i < 3; i++) {
if (a.at(i) == b.at(i)) {
return true;
}
}
return false;
}
int main() {
const int count = 100000;
std::string strings[count] = {...};
long long int matches = 0;
for (int i = 0; i < count; i++) {
for (int j = i + 1; j < count; j++) {
if (match(strings[i], strings[j])) {
matches++;
}
}
}
}
那么,有没有更有效的方法来实现这一目标?
解决方案
下面是列表(假设字符串有 3 个字符):
- 实际上是您的编译器可能尚未完成的唯一一个:传递
std::string
byconst&
,这样您每次调用函数时都不需要复制它们
bool match(const std::string& a, const std::string& b){...}
- 避免代码中无用的分支(可以通过一些分支预测算法进行优化):
// from
if (match(strings[i], strings[j])) {
matches++;
}
// to
matches = matches + match(strings[i], strings[j];
- 循环展开(编译器已经可以完成):
bool match(std::string a, std::string b) {
return a.at(0) == b.at(0) || a.at(1) == b.at(1) || a.at(2) == b.at(2);
}
- 您还可以尝试并行化这些条件(取决于架构,编译器已经可以完成)
|
,因此所有条件都可以由 ALU 并行完成,而不是 using|
必须逐步执行(短路评估):
bool match(std::string a, std::string b) {
return a.at(0) == b.at(0) | a.at(1) == b.at(1) | a.at(2) == b.at(2);
}
使用最高优化编译(可以增加编译时间),使用
-O3
使用前增量而不是后增量(后增量将生成第二个变量以在每次使用时返回,前增量没有):
for (int i = 0; i < count; ++i) {
for (int j = i + 1; j < count; ++j) {
}
}
通过这一行
std::string strings[count] = {...};
,我假设您正在使用 initializarer 列表,因此如果您使用计算实际上可以在编译时执行std::string_view
,因此在运行时没有要执行的编译(这仅适用于在编译时知道字符串的情况)减少缓存未命中,但这 100% 取决于架构
内联函数(这样你的程序就不必每次调用都跳转
match
):
// from:
bool match(const std::string& a, const std::string& b){...}
//to:
inline bool match(const std::string& a, const std::string& b){...}
- 使用
operator[]
而不是.at()
因为它不会进行任何类型的边界检查
bool match(std::string a, std::string b) {
return a[0] == b[0] | a[1] == b[1] | a[2] == b[2];
}
推荐阅读
- ios - iOS Google 登录未显示在模态呈现的视图控制器上方
- string - 替换 SAS 中的多个字符串值
- c++ - 类模板显式实例化声明
- python-3.x - matplotlib 使用 figure.canvas.draw() 和 figure.savefig() 引发错误:“ValueError: Expected 2-dimensional array, got 1”
- spring-boot - 使用一个版本的 java 库或另一个 => 使代码对两者都兼容
- python-3.x - Python 正则表达式搜索直到特定单词并排除它后面的所有内容
- javascript - 反应:自动聚焦在模态内的输入字段上
- flutter - Flutter Datetime Picker 的自定义 Picker
- c - 如何将字符串声明为 c 中函数的参数?
- django - Django 中的错误:TemplateDoesNotExist at /materialize_css_forms/whole_uni_form.html