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

5

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

For example, I am wondering if there is anything that does 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 searched and read about less , but from my understanding, it does not seem to do what I quoted.

    
asked by anonymous 13.11.2016 / 21:21

3 answers

2

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

The less function does not do what you want, although it can be used to help you. This function is used to compare two unique 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% w / o% therein is merely being used as the comparator . You could pass another existing comparer or create one to sort the list according to any other criteria, because the less algorithm interface is just created.

If your intention is to "use less code" when comparing, the best way is to actually overload the lower comparison operator ( sort ).

I've refactored the code you posted in a complete example (by the way, the next time you create a question, try to provide Minimum, Full and Verifiable example to make it easier for someone to help you) that overloads this operator. The code is below and can also be run on 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 final remarks:

  • This code overloads operator< in global scope for class operator< , so you can std::vector for any integer vector.
  • Note the use of the v1 < v2 function in the implementation of this overload. It works, but it's totally unnecessary, since it's more practical and straightforward to simply do the comparison yourself (commented line).
  • In your original code you had a variable called less , whose name is the same as the less function. Be very careful with this , because when you use the same name you run the risk of mixing the references (unless you keep the namespace for each call of std::less instead of just std::less - that is, without using less at the beginning).
  • Note how the overhead implementation does not use a numeric index as in its original implementation, but rather two iterators (one for each vector using namespace std and a ). In your original code, if the vectors were different sizes, you ran the risk of having invalid access when doing b , since v2->at(j) was incremented by the size of j .
  •   

    My choice of implementation ensures that the error mentioned in item   4 does not happen (because the loop ends when any of the   iterators arrive at the end). However, in cases where the vectors have   different sizes, the response given will be the comparison only of the   of the largest vector, with the same amount of vector elements   smaller. That's why at the beginning I said that this comparison does not   always felt. We do not know what your problem is, nor if the vectors   they will always be the same size. But in the case of different sizes, it's worth   say v1 is less than v2 even though v1 has more   elements than v2 ? No one but you can respond to this    question.

        
    14.12.2016 / 21:28
    1

    It is possible to make the element-by-element comparison between two vectors (actually between any two sequences specified by iterators) through the "mismatch" algorithm.

    The "comparison function" is a generic boolean predicate "bool f (x, y)" which can be specified in a number of ways, for example a function, or a function object, or a lambda expression. When not specified, the comparison function used is "equality" (that is, a function that compares if two elements are equal).

    The mismatch algorithm returns a std :: pair object containing the iterators (referring to the two sequences) where the "comparison" failed, or the iterator ".end ()" if the "comparison" was successful on all elements .

    Reference: link

    In the example below, the program will display "(1) all less" when the mismatch algorithm is applied to vectors v1 = {1, 2, 3} and v2 = {2, 3, 4}, and will display " (2) not all less "when the mismatch algorithm is applied to 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";
    }
    
        
    24.12.2016 / 01:10
    0

    More direct way would you set up a function where you pass as reference two vectors with your rule, returning or not values, or printing or not, maybe a swap() , there it is with 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;
        }
    }
    
        
    14.12.2016 / 19:15