1

I have inserted some elements in a 2D vector and want to know whether a given element is present in the 2D vector anywhere. Is there any quick way to find the presence of the element ?

The vector is declared as : vector < vector< int > > v;

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
asn
  • 2,408
  • 5
  • 23
  • 37
  • 1
    https://stackoverflow.com/questions/571394/how-to-find-out-if-an-item-is-present-in-a-stdvector?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – superPhreshHackerKid May 06 '18 at 19:45
  • 1
    Possible duplicate of [How to find out if an item is present in a std::vector?](https://stackoverflow.com/questions/571394/how-to-find-out-if-an-item-is-present-in-a-stdvector) – FrankS101 May 06 '18 at 19:52
  • That is for 1D vector,I hope. – asn May 06 '18 at 19:52
  • Did you mean `vector> v;` for some scalar type T? – wcochran May 06 '18 at 19:58
  • 2
    You know how to search a vector? Then just search every vector in the vector in the same way. – super May 06 '18 at 19:59
  • `vector < vector > v;` is an error, you must give a template parameter for the inner vector – M.M May 06 '18 at 22:20
  • Well, I gave that as int inside angular brackets but It vanished after posting !! – asn May 07 '18 at 03:07

3 Answers3

2

If you don't have more information about the 2D vector (like somehow sorted), then the best way would be iterating over each row of the 2D vector and using find method to check if it exist or not.

You do something like the following:

bool does_exist(const vector< vector<int> >&  v, int item){

     vector< vector<int> >::const_iterator row;

    for (row = v.begin(); row != v.end(); row++) {
        if(find(row->begin(), row->end(), item) != row->end() )
            return true;
    }

    return false;
}

You can test it with the follwing code:

#include <iostream>
#include <vector>

using namespace std;

int main(){

    int item = 12;
    vector < vector <int> > v;
    vector <int> v1;

    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);

    vector <int> v2;

    v2.push_back(4);
    v2.push_back(5);
    v2.push_back(6);

    v.push_back(v1);
    v.push_back(v2);

    if( does_exist(v, item))
        cout << "Item " << item << " exist" << endl;
    else 
        cout << "Item " << item << " does not exist" << endl;
}
eneski
  • 1,575
  • 17
  • 40
1

Not as elegant as I had hoped for. Given a 2D vector of int's:

std::vector<std::vector<int>> foo = {
    {{1, 2, 3}},
    {{5, 6, 7}},
    {{8, 9, 13, 15}}
};

you could do this to see if the 13 is present:

bool found =
    find_if(foo.begin(), foo.end(),
            [](const std::vector<int>& v) -> bool {
                return find(v.begin(), v.end(), 13) != v.end();
            }) != foo.end();
wcochran
  • 10,089
  • 6
  • 61
  • 69
  • Really, not much elegant as an answer as I had hoped for. But, iterating would be much better !! – asn May 06 '18 at 20:18
  • I prefer functional methods over imperative approaches like iteration, but dang C++ lambda syntax is ugly. – wcochran May 06 '18 at 21:20
  • Does the time complexity in any of the 2 approaches change ? – asn May 06 '18 at 21:22
  • 1
    Using functional programming style typically gives room for the compiler to optimize more, but I recommend using what you think is clearer. Both are linear O(N) searches. – wcochran May 06 '18 at 21:26
  • @wcochran *"Using functional programming style typically gives room for the compiler to optimize more"* Can you point to resources that drive the idea home? I would like to read more. – CinCout May 07 '18 at 03:27
  • @CinCout The main idea is that you are not specifying *how* to find the element (e.g., with an explicit loop), so the STL `find`/`find_if` implementation has more freedom to generate whatever code it deems best. In fact, `find` / `find_if` are "embarrassingly parallel" in this case -- e.g., a compiler could generate SIMD compare instructions on slices of the vector. To go even farther there exist parallel versions of STL algorithms : e.g., https://software.intel.com/en-us/get-started-with-pstl – wcochran May 07 '18 at 05:42
  • @CinCout There are paralyzed versions `find` and `find_if` in the `std::experimental::parallel` space: http://en.cppreference.com/w/cpp/experimental/parallelism/existing I imagine this will be standard for future C++ STL implementation. – wcochran May 07 '18 at 05:57
  • @wcochran So by *functional programming", you meant STL algorithms and not explicit loops?! I interpreted it in reverse, hence the question. – CinCout May 07 '18 at 06:17
  • @CinCout loops are an imperative construct, not a functional one. STL algorithms and lambdas are C++’s attempt to provide functional programming methods. Not as powerful as Lisp or Haskel in this area, but a good way forward. – wcochran May 07 '18 at 06:29
0

TL;DR

Use std::find().

In C++, please use the function from Standard Template Library (STL) if it has been provided.

Elaboration

Let's say you have an 2d vector

std::vector<std::vector<int> > matrix = {
   {1,2,3}, 
   {4,5,6},
   {7,8,9}
};

And if you want to iterate over all the elements in the 2d vector above.

I recommend you to use 2d iterator:

bool element_exist(const vector< vector<int> >&  input, int key){
    // 2d vector iterator
    vector< vector<int> >::iterator row_it; //iterate over each row(s)
    vector<int>::iterator col_it; //iterate over column(s)
    for (row_it = input.begin(); row_it != input.end(); row_it++) { // iterate each row(s)
        for (col_it = row_it->begin(); row_it != row_it->end(); col_it++) {
            if(find(row_it->begin(), row_it->end(), key) != row_it->end())
                return true;
        }
    }
}

and you can use another boolean variable to get the return value of the function key_exist

bool_var = element_exist(matrix, key);

Whole program

#include <vector>
#include <iostream>
using namespace std;

bool element_exist(const vector< vector<int> >&  input, int key){
    // 2d vector iterator
    vector< vector<int> >::const_iterator row_it; //iterate over each row(s)
    vector<int>::const_iterator col_it; //iterate over column(s)
    for (row_it = input.begin(); row_it != input.end(); row_it++) { // iterate each row(s)
        for (col_it = row_it->begin(); row_it != row_it->end(); col_it++) {
            if(find(row_it->begin(), row_it->end(), key) != row_it->end())
                return true;
        }
    }
}

int main() {
    // declaration
    bool bool_var = false; // default false
    std::vector<std::vector<int> > matrix = {{1,2,3}, {4,5,6},{7,8,9}};

    bool_var = element_exist(matrix,1);
    cout << "bool_var: " << bool_var << endl;

    return 0;
}

Result

bool_var: 1
WY Hsu
  • 1,837
  • 2
  • 22
  • 33
  • somebody mentioned this post, so I put it here: [How to find out if an item is present in a std::vector?](https://stackoverflow.com/questions/571394/how-to-find-out-if-an-item-is-present-in-a-stdvector?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa) – WY Hsu Feb 06 '19 at 15:10
  • more info [Iterating over 2-dimensional STL vector c++ ][https://stackoverflow.com/questions/3131991/iterating-over-2-dimensional-stl-vector-c] – WY Hsu Feb 06 '19 at 15:20