How to lexicographically compare two vectors in reverse order?

390 Views Asked by At

If I want to compare two vectors in lexicographical order, I can do as follows:

int main() {
    std::vector<int> a{0, 7, 8, 9};
    std::vector<int> b{1, 2, 3, 4};

    std::cout << std::boolalpha;
    std::cout << "a < b returns " << (a < b) << '\n';
}

But doing the same in reverse order fails to compile:

int main() {
    std::vector<int> a{3, 2, 1};
    std::vector<int> b{9, 8, 7, 6};

    std::cout << std::boolalpha;
    std::cout << "revrese a < reverse b returns " << ((a | std::views::reverse) < (b | std::views::reverse)) << '\n';
}

The latter code fails with:

<source>:23:81: error: no match for 'operator<' (operand types are 'std::ranges::reverse_view<std::ranges::ref_view<std::vector<int> > >' and 'std::ranges::reverse_view<std::ranges::ref_view<std::vector<int> > >')
   23 |     std::cout << "reverse a < reverse b returns " << ((a | std::views::reverse) < (b | std::views::reverse)) << '\n';
      |                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                          |                           |
      |                                                          reverse_view<[...]>         reverse_view<[...]>

So, how to do achieve this properly?

I needed this because, I was creating a custom big integer class. In that, I was storing nodes in little endian order. Now, to compare if two integers are equal, first I compare their sizes. Then I would need to compare equal sized vectors in lexicographical order of their reverse view.

2

There are 2 best solutions below

1
user17732522 On BEST ANSWER

operator< is not defined for std::views::reverse and others. There is however a normal algorithm as normal function template for it in the standard library: std::lexicographical_compare with iterator interface and std::ranges::lexicographical_compare with range interface.

std::cout << "revrese a < reverse b returns "
          << std::ranges::lexicographical_compare(a | std::views::reverse, b | std::views::reverse) 
          << '\n';
1
Another HM On

As @user17732522 said you can use std::ranges::lexicographical_compare && std::views::reverse but if you want use c++11 you can simply use reverse iterators with std::lexicographical_compare.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
  std::vector<int> a{0, 7, 8, 9};
  std::vector<int> b{1, 2, 3, 4};

  std::cout << std::boolalpha;
  std::cout << "a < b returns "
            << std::lexicographical_compare(a.cbegin(), a.cend(), b.rbegin(),
                                            b.rend())
            << '\n';
}