最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

stl - C++ How to convert a for loop to std::count_if - Stack Overflow

programmeradmin4浏览0评论

Here's a code that, for each element, counts the number of elements that are not connected to it.

bool conn[100][100];
for(int i=0; i<N; i++){
  int cnt=0;
  for(int j=0; j<N; j++) cnt+=!(conn[i][j]||conn[j][i]);
  std::cout<<cnt<<"\n";
}

I want to convert it into std::count_if statement.

for(int i=0; i<N; i++){
    std::cout<<count_if(conn[i], conn[i]+N, [&](){auto k; return !(conn[i][k]||conn[k][i]);})<<"\n";
}

How can I do this? Seems like I should access to index of iterator in lambda function.

Here's a code that, for each element, counts the number of elements that are not connected to it.

bool conn[100][100];
for(int i=0; i<N; i++){
  int cnt=0;
  for(int j=0; j<N; j++) cnt+=!(conn[i][j]||conn[j][i]);
  std::cout<<cnt<<"\n";
}

I want to convert it into std::count_if statement.

for(int i=0; i<N; i++){
    std::cout<<count_if(conn[i], conn[i]+N, [&](){auto k; return !(conn[i][k]||conn[k][i]);})<<"\n";
}

How can I do this? Seems like I should access to index of iterator in lambda function.

Share Improve this question edited Feb 15 at 16:45 Tim Diekmann 8,47611 gold badges48 silver badges72 bronze badges asked Feb 15 at 5:12 navyismnavyism 233 bronze badges 11
  • You seem to need std::valarray – 3CxEZiVlQ Commented Feb 15 at 5:19
  • 4 @3CxEZiVlQ Very few people need std::valarray. – Passer By Commented Feb 15 at 5:19
  • 1 Personally, I'd keep the code as is. It's clear what's going on. It may be possible to press std::count_if into service with some complicated lambda, but it'd only obscure the logic. – Igor Tandetnik Commented Feb 15 at 5:29
  • 1 conn is N by N boolean adjoint matrix. -- There is no such type as "adjoint matrix" in C++. Please be specific as to the actual type conn is, so that we get a clearer picture. – PaulMcKenzie Commented Feb 15 at 5:31
  • 1 std::count_if() is not really suitable for your task without a significant amount of fiddling. The overload of std::count_if that accepts a function object ONLY passes the value of an element (obtained by dereferencing an iterator) to the function. It doesn't pass the iterator itself, nor does it pass indices. Your code requires being able to access indices. Sticking with your loops is among the simplest (and more maintainable) options. – Peter Commented Feb 15 at 13:11
 |  Show 6 more comments

2 Answers 2

Reset to default 2

If you really want to use std::count_if and have access to C++20 ranges, you can run it on cartesian product of indices:

template <size_t N>
size_t count_disconnected(const bool (&matrix)[N][N]) {
    const auto range = std::views::iota<size_t>(0, N);
    const auto product = std::views::cartesian_product(range, range);
    return std::ranges::count_if(product, [&matrix](const auto& pair) {
        const auto [i, j] = pair;
        return !matrix[i][j] && !matrix[j][i];
    });
}

Please note that since your predicate is symmetric, both your algorithm and this one will double count everything except the diagonal. You can fix this by changing the second loop condition to j < i (or <= if still want to check the diagonal), or adding j < i && to the predicate.

2d arrays in C and C++ are successions of 1 d arrays in memory. Use this to calculate in a single for_each connection to element neq (prefering for_each that does not return value to count if). A single line of the matrix has to be observed

bool conn [3] [3] = {
  {false, true, false},
  {true, false, true},
  {false, false, false}
};

const int N (3);
#include <iostream>
#include <algorithm>


int main (int argc, char* argv []) {
  auto nel ((int) 1), //element number
       nct (0);
  auto conn1d ((bool*) &conn);
  std::for_each ((const bool*) &conn1d [nel * N], (const bool *) &conn1d [(nel+1)*N], [&nct] (const auto& b) {
    nct += b?1:0;
  });

  std::cout << "\tnb of element connected to element " << nel << " is " << nct << std::endl;
  std::cout << "\tnb of element unconnected to element " << nel << " is " << N-nct << std::endl;

  return 0;
}
发布评论

评论列表(0)

  1. 暂无评论