If I have a list of strings for example:
Dog
Cat
Tree
NiceCar
Car
And then I get one string from list what is the fastest way to check them? I was thinking about some hashing and then to comparing the hashes.
std::hash<std::string> hasher;
std::string stringToCheck = "Car";
switch (hasher(stringToCheck))
{
case hasher("Dog"):
break;
// and so on, I will ofcourse hash the whole list on program start and then compare against that.
}
I will ofcourse hash the whole list on program start and then compare against that.
If that's the case, I would suggest using a standard library utility - std::unordered_set
, which internally stores the data and uses hashing to search for it:
int main() {
std::unordered_set<std::string> strings = {
"dog", "cat", "tree", "nicecar", "car"
};
std::string to_search = "dog";
std::cout << strings.contains(to_search); // true
std::cout << strings.contains("not there"); // false
}
But do note that this incurs additional costs - the creation of the set (and, in reality, any mean of hashing the data beforehand) will take additional time. This is only worth it if you query the elements from the set multiple times. Otherwise, plain old ==
will be sufficient. To compare the approaches you can't do anything else than measure the time taken of each of them.
EDIT: It appears that you wish to retain the switch-case
functionality. For completeness, to achieve similar effect I would recommend not a set, but a map. Specifically, std::unordered_map
:
int main() {
std::unordered_map<std::string, void (*)()> cases = {
{"dog", [](){
std::cout << "this is a dog";
}},
{"cat", [](){
std::cout << "meow";
}},
{"tree", [](){
std::cout << "to isengard";
}},
{"nicecar", [](){
std::cout << "goes brrrr";
}},
{"car", [](){
std::cout << "wroom";
}}
};
const std::string to_search = "dog";
cases[to_search]();
}
This prints this is a dog
.
The only upside of this approach vs the switch()
approach is that with this container, you can dynamically add, remove and modify the keys and the executed code.