How to compare one to one all the elements of two vectors?

Asked

Viewed 4,668 times

5

Having two vectors of int of the same size, there is some native language function comparing the position x of the first vector with the position x of the second vector, doing this for all positions generating a general result?

For example, I wonder if there is something that accomplishes this in a more direct way:

// vector de int v1 = 5 3 8
// vector de int v2 = 4 1 6

bool less = true;
for (unsigned int j = 0; j < v1->size(); j++) {
  if (v2->at(j) > v1->at(j))
    less = false;
}

I researched and read about the Less, but, from my understanding, he doesn’t seem to do what I’ve quoted.

  • 2

    There is nothing ready, there are several ways to do this, but it needs a clear criterion, it is not clear what to ask in the question.

  • @bigown the example I gave would be one of the ways to accomplish this if the criterion is "an element of v2 is less than an element of v1 for all vector positions", right? Also, by your comment, then there is nothing ready to accomplish something with that criterion, right?

  • You have already used this phrase and it is not clear to define the problem you are trying to solve. You can interpret it in several ways.

  • @bigown I’m sorry, but I don’t know how to be clearer. I believe you managed to understand what the code of the question does, right?

  • Maybe, but it could be the wrong solution if the problem is wrong.

  • @bigown I will try to explain again using the code in the question. In this code, considering that v1 and v2 have the values that are in the comments, after the execution of the loop the variable "Less" will have the true value, because for each possible index (the variable k) the value of v2 in this index is less than the value of v1 in this same index. So "being smaller" would be the criterion. But anyway, if you believe that it rained in the wet and I now repeated what I said before, no problem, because I already consider that you answered my question in your first comment saying that there is nothing ready to do this.

Show 1 more comment

3 answers

2


There is no native function that does this because this comparison makes no sense as a general purpose resource. That is, you may have some need to make this comparison, but a vector has very broad use and an individual comparison of its numbers can be implemented with different nuances (more details at the end).

The function less does not do what you want, although it can be used to help you. This function serves to compare two single values/objects. If you look at the example of the documentation you referenced, you will see the following calls:

int foo[]={10,20,5,15,25};
. . .
std::sort (foo, foo+5, std::less<int>()); // 5 10 15 20 25

That is, what the last line (where less is being used) does is sort the elements in foo in ascending order. The less there is merely being used as the comparator. You could pass another existing comparator or or create one of your own to sort the list according to any other criteria, because the interface of the algorithm sort is rightly created for such.

If your intention by "more direct way" is to use less code when making the comparison, the best way is to really overload the smaller comparison operator (operator<).

I redid the code you posted in a full example (by the way, next time you create a question, try to provide the Minimum, Complete and Verifiable Example to make it easier for someone interested in helping you) to overload that operator. The code is below and can be executed as well in Ideone:

#include <vector>
#include <iostream>
#include <functional> // Necessário para usar o std::less

using namespace std;

// Sobrecarrega o operador de menor para a classe `vector`
bool operator<(const vector<int>& a, const vector<int>& b)
{
    vector<int>::const_iterator aIt = a.begin();
    vector<int>::const_iterator bIt = b.begin();

    bool ret = true;
    while(aIt != a.end() && bIt != b.end())
    {
        //if(*aIt >= *bIt) // <== Mais simples e mais claro. Portanto, melhor.
        if(!less<int>()(*aIt, *bIt))
        {
            ret = false;
            break;
        }

        ++aIt;
        ++bIt;
    }
    return ret;
}

int main()
{
    vector<int> v1 = {5, 3, 8};
    vector<int> v2 = {4, 1, 6};

    // Imprime os vetores para conferência
    cout << "v1: ";
    for (auto i: v1)
        std::cout << i << ' ';
    cout << endl;

    cout << "v2: ";
    for (auto i: v2)
        std::cout << i << ' ';
    cout << endl;

    // Usa diretamente o operador para verificar se v2 é menor do que v1
    cout << "v2 < v1? " << (v2 < v1 ? "SIM" : "NAO") << endl;

    return 0;
}

Some concluding remarks:

  1. This code overloads operator< in the overall scope for the class std::vector, so that you can do v1 < v2 for any vector of integers.
  2. Note the use of the function less in implementing this overload. It works, but is totally unnecessary, since it is more practical and straightforward to simply make the comparison yourself (commented line).
  3. In your original code you had a variable called less, whose name is the same as the function std::less. Be very careful with that, because using the same name you run the risk of mixing the references (unless you keep the namespace every call std::less instead of just less - that is, without using the using namespace std at first).
  4. Note how the overload implementation does not use a numeric index as in its original implementation, but rather two iterators (one for each vector a and b). In your original code, if the vectors have different sizes, you would run the risk of having an invalid access while doing v2->at(j), since j was increased according to the size of v1.

My choice of implementation ensures that the error mentioned in the item 4 does not happen (because the loop ends when any of the iterators reach the end). However, in cases where the vectors have different sizes, the answer will be to compare only the part initial of the larger vector, with the same amount of vector elements minor. Why there at the beginning I said that this comparison does not sense always. We don’t know what your problem is, nor if the vectors will always have the same size. But in case of different sizes, it is worth say that v2 is less than v1 even though v2 has been plus elements of what v1? No one but you can answer that question.

  • Luiz, in your example you use the namespace std, but within the two ties in main you present it instead of hiding it. There is some reason for this?

  • 1

    No, no reason other than I have forgotten there. Sorry. :) Like I did using namespace std; there at the beginning, no need to specify the namespace when doing std::cout. I mean, just use cout there in the bonds.

1

It is possible to compare element by element between two vectors (actually between any two sequences specified by Iterators) through the algorithm "Mismatch".

The "comparison function" is a generic Boolean predicate "bool f(x,y)" that can be specified in several ways, for example a function, or a Function Object, or a lambda expression. When unspecified, the comparison function used is "equality" (i.e., function that compares whether two elements are equal).

The Mismatch algorithm returns an Std::pair object containing the Iterators (referring to the two sequences) where the "comparison" failed, or the iterator ". end()" whether the "comparison" was successful in all elements.

Reference: http://en.cppreference.com/w/cpp/algorithm/mismatch

In the example below, the program will display "(1) all Less" when the Mismatch algorithm is applied to the vectors v1 = { 1, 2, 3 } and v2 = { 2, 3, 4 }, and will display "(2) not all Less" when the Mismatch algorithm is applied to the vectors v3 = { 1, 2, 3 } and v4 = { 1, 3, 4 }.

#include <algorithm> // para mismatch
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> v1 { 1, 2, 3 };
   vector<int> v2 { 2, 3, 4 };

   vector<int> v3 { 1, 2, 3 };
   vector<int> v4 { 1, 3, 4 };

   auto result1 = mismatch(v1.begin(), v1.end(), v2.begin(), less<int>());
   if (result1.first == v1.end())
      cout << "(1) all less\n";
   else
      cout << "(1) not all less\n";

   auto result2 = mismatch(v3.begin(), v3.end(), v4.begin(), less<int>());
   if (result2.first == v3.end())
      cout << "(2) all less\n";
   else
      cout << "(2) not all less\n";
}

0

More direct way would be to assemble a function where you pass as reference two vectors with your rule, returning or not values, or printing or not, maybe a swap(), It’s up to you! Follow an example!

void compare(vector<int>& vec1, vector<int>& vec2){
    for (int i = 0; i < vec1.size(); i++){
        if (vec1[i] == vec2[i])
            cout << "os valores da posição :" << i << "são iguais!" << endl;
        if (vec1[i] < vec2[i])
            cout << "o valor("<< vec1[i] <<") do vec1 na posição:" << i << "é menor que o vec2!" << endl;
        else
            cout << "o valor(" << vec2[i] << ") do vec2 na posição:" << i << "é menor que o vec1!" << endl;
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.