2

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.

Sourav Kannantha B
  • 2,860
  • 1
  • 11
  • 35
  • I can use `std::reverse`. But that mutates the vector, which is not desired. – Sourav Kannantha B Feb 17 '23 at 07:56
  • 2
  • 1
    Does this answer your question? [Is there a standard way to compare two ranges in C++?](https://stackoverflow.com/questions/5405203/is-there-a-standard-way-to-compare-two-ranges-in-c) – kiner_shah Feb 17 '23 at 08:02
  • 3
    @kiner_shah OP wants to compare the reversed vectors via `<`, the question you propose as dupe is about equality, where reversed or not does not matter – 463035818_is_not_an_ai Feb 17 '23 at 08:06
  • @463035818_is_not_a_number, look at this answer in that link: https://stackoverflow.com/a/5405898/4688321 – kiner_shah Feb 17 '23 at 08:07
  • 3
    @kiner_shah the fact that there is an answer that is slightly related does not make the questions a duplicate. Consider that the answer you link could be deleted or modified to still match the question asked there but to not match the question asked here. That question is about comparing for eqaulity, this question is about comparing `<` reversed. – 463035818_is_not_an_ai Feb 17 '23 at 08:09
  • @463035818_is_not_a_number, so you mean to say that `<` is not comparison? Also, there is another answer https://stackoverflow.com/a/67734453/4688321 in the same page which is even better. If you look at the question title, it says comparing two ranges. Now, if the answers there are specifically focused on equality, despite the question not specifically asking for equality, it's not my fault! – kiner_shah Feb 17 '23 at 08:12
  • 2
    @kiner_shah i mean that `==` / equality and lexicographical comparison / `<` are totally different. The question you link is about the former, the question here is about the latter. The answers on the question you link focus on equality because thats what is being asked for there, but not here. – 463035818_is_not_an_ai Feb 17 '23 at 08:14
  • 1
    @kiner_shah the question you link does not state it totally clear, but from the code one can see that they expect the function to return `true` for two ranges that are equal. – 463035818_is_not_an_ai Feb 17 '23 at 08:17
  • 1
    @463035818_is_not_a_number, ok agree it's kind of indirectly saying equality. – kiner_shah Feb 17 '23 at 08:21

2 Answers2

7

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';
user17732522
  • 53,019
  • 2
  • 56
  • 105
  • For future reference, I'm using this solution, with slight modification as in shown in [this](https://codereview.stackexchange.com/q/283373/241242). – Sourav Kannantha B Feb 17 '23 at 18:12
1

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';
}

Sourav Kannantha B
  • 2,860
  • 1
  • 11
  • 35
Another HM
  • 148
  • 10