C++如何将统计非连通元素的for循环转换为std::count_if
正确实现方案
你遇到的问题是std::count_if的lambda默认接收迭代指向的元素值,但你需要的是元素的索引。以下是几种可行的解决方法:
方法1:通过元素地址计算索引
利用当前元素的地址减去行起始地址,直接得到索引k,兼容性好且无需额外依赖:
#include <algorithm> #include <iostream> bool conn[100][100]; int N; int main() { for (int i = 0; i < N; ++i) { bool* row_start = conn[i]; int cnt = std::count_if(row_start, row_start + N, [&](bool elem) { int k = &elem - row_start; return !(conn[i][k] || conn[k][i]); }); std::cout << cnt << "\n"; } }
方法2:使用外部计数器
声明一个外部变量k,在lambda中每次调用后递增,利用std::count_if的顺序遍历特性实现索引追踪:
for (int i = 0; i < N; ++i) { int k = 0; int cnt = std::count_if(conn[i], conn[i] + N, [&](bool) { bool result = !(conn[i][k] || conn[k][i]); ++k; return result; }); std::cout << cnt << "\n"; }
这个方法逻辑简单,无需地址运算,适合所有支持C++11及以上的编译器。
方法3:C++20 用std::views::enumerate(推荐)
如果编译器支持C++20,可直接通过范围库的enumerate获取索引和元素对,代码可读性最高:
#include <ranges> #include <algorithm> for (int i = 0; i < N; ++i) { auto row = conn[i]; int cnt = std::ranges::count_if(std::views::enumerate(row), [&](auto&& idx_elem) { int k = idx_elem.first; return !(conn[i][k] || conn[k][i]); }); std::cout << cnt << "\n"; }
内容的提问来源于stack exchange,提问作者navyism
相关产品推荐
相关产品推荐

