简体   繁体   中英

How to get an element (struct) in an array by a value in the struct

Let's say I have this struct containing an integer.

struct Element 
{
  int number;
  Element(int number) 
  {
    this->number = number;
  }
};

And I'm gonna create a vector containing many Element structs.

std::vector<Element> array;

Pretend that all the Element structs inside array have been initialized and have their number variable set. My question is how can I instantly get an element based on the variable number?

It is very possible to do it with a for loop, but I'm currently focusing on optimization and trying to avoid as many for loops as possible.

I want it to be as instant as getting by index:

Element wanted_element = array[wanted_number]

There must be some kind of overloading stuff, but I don't really know what operators or stuff to overload.

Any help is appreciated:)

With comparator overloading implemented, std::find is available to help:

#include <iostream>
#include <vector>
#include <algorithm>
struct Element 
{
  int number;
  Element(int number) 
  {
    this->number = number;
  }

  bool operator == (Element el)
  {
      return number == el.number;
  }

};


int main()
{

    std::vector<Element> array;
    std::vector<int> test;
    for(int i=0;i<100;i++)
    {
        auto t = clock();
        test.push_back(t);
        array.push_back(Element(t));
    }
    auto valToFind = test[test.size()/2];
    std::cout << "value to find: "<<valToFind<<std::endl;
    Element toFind(valToFind);
    auto it = std::find(array.begin(),array.end(),toFind);
    if(it != array.end())
        std::cout<<"found:" << it->number <<std::endl;
    return 0;
}

The performance on above method depends on the position of the searched value in the array. Non-existing values & last element values will take the highest time while first element will be found quickest.

If you need to optimize searching-time, you can use another data-structure instead of vector . For example, std::map is simple to use here and fast on average (compared to latest elements of vector-version):

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

struct Element 
{
  int number;
  Element(){ number = -1; }
  Element(int number) 
  {
    this->number = number;
  }

};


int main()
{

    std::map<int,Element> mp;
    std::vector<int> test;
    for(int i=0;i<100;i++)
    {
        auto t = clock();
        test.push_back(t);
        mp[t]=Element(t);
    }
    auto valToFind = test[test.size()/2];
    std::cout << "value to find: "<<valToFind<<std::endl;
    auto it = mp.find(valToFind);
    if(it != mp.end())
        std::cout<<"found:" << it->second.number <<std::endl;
    return 0;
}

If you have to use vector, you can still use the map near the vector to keep track of its elements the same way above method just with extra memory space & extra deletions/updates on the map whenever vector is altered.

Anything you invent would with success would look like hashing or a tree in the end. std::unordered_map uses hashing while std::map uses red-black tree.

If range of values are very limited, like 0-to-1000 only, then simply saving its index in a second vector would be enough:

vec[number] = indexOfVector;
Element found = array[vec[number]];

If range is full and if you don't want to use any map nor unordered_map, you can still use a direct-mapped caching on the std::find method. On average, simple caching should decrease total time taken on duplicated searches (how often you search same item?).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM