Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find item using multiple search values in c++?

Tags:

c++

Conceptually my data represents a table like this one

+-------+------+------+------+------+  
|  ID   | Val1 | Val2 | Val3 | Val4 |  
+-------+------+------+------+------+  
| Name1 | a    | b    | c    | d    |  
| Name2 | a    | b    | c    | e    |  
| Name3 | h    | b    | c    | d    |  
| Name4 | i    | j    | k    | l    |  
+-------+------+------+------+------+  

Currently I am free to choose how that data will be stored. Essentially I have IDs with some values, which are assigned to the IDs. A set of values is unique to the ID (no set will be repeated for another ID). Individual values can be repeated across IDs.

Now, what I need to do in C++ is to find the name by using a set of Values. So essentially something like this:

std::string findID(char val1, char val2, char val3, char val4)
{
    //Do something to find the corresponding Name

    return result;
}

I am currently a bit bumbed on how to go about this. I thought about using a map with tuples, but providing a hash function for the tuples seems like overcomplicating the problem. So basically like described here: Using tuple in unordered_map

Is there a simpler solution that I just seem to overlook?

like image 723
FreddyKay Avatar asked Jan 28 '23 19:01

FreddyKay


2 Answers

If all values are characters, I think you'd better transform each line of your table into strings and provide a hash table for the couple ID/stringID. When you get 5 values as char to test you then just have to concat them and run your search.

like image 68
Benjamin Barrois Avatar answered Feb 14 '23 05:02

Benjamin Barrois


Yes, the easiest way is to store a mapping from a tuple of values to a name. If your values are chars, however, it's the easiest to simply use string for that, and pack everything into std::unordered_map<std::string, std::string>, the key being all values packed into the string, and the value your name.

If your values aren't chars, it's still not that complex. Instead of using a tuple, you might just use a structure:

struct Key {
    std::array<Value, n> vals;
};

And then provide std::hash instance that'd fold the array with boost::hash_combine:

class KeyHash  {
    std::size_t operator()(Key const& k)
    {
        std::size_t h = 42;
        for (Value const& v : k.vals) {
            boost::hash_combine(h, v);
        }
        return h;
    }
};

The question you've linked and the presented solution aren't bad either, though, and are generic enough to be put into some reusable library.

like image 20
Bartek Banachewicz Avatar answered Feb 14 '23 03:02

Bartek Banachewicz