Reputation: 7101
Lets suppose that I have a persons struct:
struct Person {
char name[100];
char surname[100];
unsigned int age;
};
I would like to find out the fastest way to search and find if another struct with the same values (same name, same surname, same age) already exist in a vector.
Please keep in mind that I have million of those in a vector.
Thanks
Upvotes: 1
Views: 1304
Reputation: 8677
Based on the comments in the question, specifically
No, I mean a set which describes that 10 was duplicate to 2, 12, 54, etc or 2 was duplicate to 10, 12, 54
it sounds like the data structure you actually want is std::multimap
(or std::unordered_multimap
if you have C++11 and don't care about order). Multimaps will take care of the bookkeeping you would have to do on your own with M M.'s solution (which is nice overall, except that you have to maintain an additional container with duplicate description). std::multimap
does the extra bookkeeping for you.
#include <map> // or <unordered_map>
#include <string>
#include <tuple> // std::tie()
#include <utility> // std::make_pair()
struct Person {
std::string name;
std::string surname;
unsigned int age;
bool operator<(const Person &x) const
{
return std::tie(name, surname, age) < std::tie(x.name, x.surname, x.age);
}
};
extern bool tryReadNextPersonFromFile(Person &, size_t & record_id);
int main()
{
std::multimap<Person, size_t> persons;
Person p;
size_t rid;
while(tryReadNextPersonFromFile(p, rid)) {
persons.insert(std::make_pair(p, rid));
}
// ...
p = ...
size_t howMany = persons.count(p);
if(0 == howMany) { /* not found ... */ }
else {
auto eq_range = persons.equal_range(p);
for(auto it=eq_range.first; it != eq_range.second; ++it) {
size_t pRecordID = it->second;
// ...
}
}
}
I'm using a lot of C++11 syntax (like auto
) for brevity, but this idea works just as well for C++03. Since you probably haven't heard of multimaps before (or at least are unfamiliar with the STL interface), be sure to check out eg, some documentation on what you can do with it and how.
Upvotes: 0
Reputation: 56479
Here is a possibility:
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <tuple>
struct Person {
std::string name;
std::string surname;
unsigned int age;
bool operator<(const Person &x) const
{
return std::tie(name, surname, age) < std::tie(x.name, x.surname, x.age);
}
};
int main()
{
std::vector<Person> v;
// ...
std::set<Person> s;
for (const auto &x : v)
{
auto i = s.insert(x);
if (!i.second)
{
// x is duplicated
}
}
}
To your comment, you can sort your vector by this way:
std::sort(v.begin(), v.end()); // Operator < is overloaded
Upvotes: 2