0

I want to iterate through a vector and want to get count of greater elements in another vector. I tried below code snippet, unfortunately it does not work this way.

sort(begin(vec1),end(vec1));
sort(begin(vec2),end(vec2));

for(int i = 0; i < vec1.size(); i++)
{
    int val = vec1[i];
    count_if(begin(vec2),end(vec2),[](int x) { return (x > val); });
}
Bharat Pawar
  • 3
  • 1
  • 5
  • 3
    You have to capture `val` in the lambda. `[val](int x) { ... }` – Mestkon May 19 '20 at 11:12
  • Also if these are `std::vector` you can use `vec1.begin()` and `vec1.end()`. – anastaciu May 19 '20 at 11:21
  • Once arrays are sorted, you can have this information in linear time instead of quadratic time. – Jarod42 May 19 '20 at 11:22
  • 1
    @anastaciu What would be the advantage of using `vec1.begin()` and `vec1.end()`? I recommend to use `std::begin` and `std::end` because it's more generic and it's easier to switch the container type: https://stackoverflow.com/questions/7593086/why-use-non-member-begin-and-end-functions-in-c11 – Thomas Sablik May 19 '20 at 11:23
  • @ThomasSablik, as far as I can tell there is no tangible difference, that's why I said you can, with no strings attached, it's a matter of style, in fact I believe that for this container `std::begin` calls `std::vector::begin()` so you might as well use it to begin with. – anastaciu May 19 '20 at 11:29
  • 1
    @anastaciu Yes, for this container type there is no difference (no advantage and no disadvantage) but if OP changes the code to use arrays it will work without other changes. – Thomas Sablik May 19 '20 at 11:32
  • @ThomasSablik It's more generic, yes that's an advantage, it's also C++11, that can be a disadvantage. – anastaciu May 19 '20 at 11:33
  • 1
    @anastaciu It's a 9 year old standard. Even GCC 4.8.5 and IBM z-series supports C++11. OP uses lambdas ;-) You shouldn't avoid modern C++ because there are some outdated compilers that doesn't support it. – Thomas Sablik May 19 '20 at 11:36
  • @ThomasSablik, touché :) – anastaciu May 19 '20 at 11:38
  • But C++17 to replace `vec.size()` into `std::size(vec)`... – Jarod42 May 19 '20 at 12:14

1 Answers1

0

If you want to count how many elements in vec2is greater than the i'th element in vec1 then you are doing it correct and just have to capture val in the lambda

for(int i = 0; i < vec1.size(); i++)
{
    int val = vec1[i];
    auto res = count_if(begin(vec2),end(vec2), [val](int x) { return (x > val); });
}

but if you want to compare each element in vec2 with the corresponding element in vec1 you have to do it manually.

int count = 0;
//here the sizes of vec1 and vec2 must be equal
for (auto it1 = begin(vec1), it2 = begin(vec2); it1 != end(vec1); ++it1, ++it2) {
    if (*it2 > *it1)
        ++count;
}

EDIT: As @Jarod42 commented. It is possible to use an algorithm for the second case

auto res = std::transform_reduce(begin(vec2), end(vec2), begin(vec1), 0,
    std::plus<>(), std::greater<>());
Mestkon
  • 3,532
  • 7
  • 18
  • 1
    There is [`std::transform_reduce`](https://en.cppreference.com/w/cpp/algorithm/transform_reduce) (C++17) for second snippet: `auto count = std::transform_reduce(begin(vec1), end(vec1), begin(vec2), 0, std::plus<>{}, std::greater<>{});` [Demo](https://godbolt.org/z/bL8QU8) – Jarod42 May 19 '20 at 12:25
  • @Jarod42 You are absolutely correct. I haven't used that before :) – Mestkon May 19 '20 at 12:44