I need a function that needs to check if the input (std::string) is unique and return its corresponding enum value.
I already have been able to implement this function with just a simple vector, which checks if the input is unique.
it should return enumE::HELLO.
I tried to adapt the code above for the vector to suit this function, but I am not really getting anywhere.
Based on the description of your example, here is a quick implementation. Of course, the logic may not be entirely what you wrote, but I am sure you can tweak it.
Why would you iterate through the whole string if std::string has a std::string::find function which will find a substring for you?
Is it necessary to go through all the trouble you wrote above? Does the code need to be that dense and unreadable?
Feel free to play around with that function and implement your logic.
Related
I have vector of strings. It contains some names. I need to search whether particular string is present in the vector. Eg: vector of string contains "Name" and "Age". Search string is "NameXYZ". So I have to search whether "NameXYZ" contains any of the vector element. Since one of the vector element is "Name", it should return true. Is there any possibility to achieve this without iterating.
The answer is NO.
It's impossibile to search something in a vector without iterating.
The vector is unorder and unmapped container so you need to iterating to it to find something.
I attach you this link to the cppreference site:
std::vector - cppreference.com
The more complex is answer is SOMETIMES
What you are looking for is something like a hash set. Or for your situation hash map with Key=Name and Value=Age.
This works by defining a function that turns a string into a number, called a hash. When you want to test whether the string is in the list, you calculate what number it has. You then get a list of potential candidates and iterate through those.
If you are lucky, every string has a unique number and you need to test at most one string. You still have to search for the number, but if you use the standard container, you can be certain that it is optimized. Unless you want to spend a long time making your own, it's a simple easy win.
However, be aware that it is very hard to get any search faster than O(Log(N)) complexity. This method is still O(log(N)) complex under the hood, as it has to still search for the hash.
I'm writing simple class for undirected graph's representation. Within my class I use adjacency list for graph representation. I would like to add API method, which returns link to some iterable substance, containing vertexes, adjacent to given vertex.
I have the following idea about this method. First - create dynamically allocated std::vector and handle it with shared_ptr. Second - fill vector with proper vertexes numbers and return the link to this vector. So it's prototype looks like:
const std::vector<int>& adjacent(int vertex);
Is it a good idea? Can I do better?
Regards,
Anton
The idea may work, but i strongly recommend you against it. It will be very error prone, and this function definition will look buggy to many other programmers who look at it.
I'd recommend you return vector by value, and do not think about this kind of optimizations until you come to the point where you really need them ( ie - your app is slow, and you are perfectly sure this is the bottleneck ).
If you want to avoid vector copying you can pass vector to this function by reference, so that it will be filled inside.
Usually, entities and components or other parts of the game code in data-driven design will have names that get checked if you want to find out which object you're dealing with exactly.
void Player::Interact(Entity *myEntity)
{
if(myEntity->isNearEnough(this) && myEntity->GetFamilyName() == "guard")
{
static_cast<Guard*>(myEntity)->Say("No mention of arrows and knees here");
}
}
If you ignore the possibility that this might be premature optimization, it's pretty clear that looking up entities would be a lot faster if their "name" was a simple 32 bit value instead of an actual string.
Computing hashes out of the string names is one possible option. I haven't actually tried it, but with a range of 32bit and a good hashing function the risk of collision should be minimal.
The question is this: Obviously we need some way to convert in-code (or in some kind of external file) string-names to those integers, since the person working on these named objects will still want to refer to the object as "guard" instead of "0x2315f21a".
Assuming we're using C++ and want to replace all strings that appear in the code, can this even be achieved with language-built in features or do we have to build an external tool that manually looks through all files and exchanges the values?
Jason Gregory wrote this on his book :
At Naughty Dog, we used a variant of the CRC-32 algorithm to hash our strings, and we didn't encounter a single collision in over two years of development on Uncharted: Drake's Fortune.
So you may want to look into that.
And about the build step you mentioned, he also talked about it. They basically encapsulate the strings that need to be hashed in something like:
_ID("string literal")
And use an external tool at build time to hash all the occurrences. This way you avoid any runtime costs.
This is what enums are for. I wouldn't dare to decide which resource is best for the topic, but there are plenty to choose from: https://www.google.com/search?q=c%2B%2B+enum
I'd say go with enums!
But if you already have a lot of code already using strings, well, either just keep it that way (simple and usually enough fast on a PC anyway) or hash it using some kind of CRC or MD5 into an integer.
This is basically solved by adding an indirection on top of a hash map.
Say you want to convert strings to integers:
Write a class wraps both an array and a hashmap. I call these classes dictionaries.
The array contains the strings.
The hash map's key is the string (shared pointers or stable arrays where raw pointers are safe work as well)
The hash map's value is the index into the array the string is located, which is also the opaque handle it returns to calling code.
When adding a new string to the system, it is searched for already existing in the hashmap, returns the handle if present.
If the handle is not present, add the string to the array, the index is the handle.
Set the string and the handle in the map, and return the handle.
Notes/Caveats:
This strategy makes getting the string back from the handle run in constant time (it is merely an array deference).
handle identifiers are first come first serve, but if you serialize the strings instead of the values it won't matter.
Operator[] overloads for both the key and the value are fairly simple (registering new strings, or getting the string back), but wrapping the handle with a user-defined class (wrapping an integer) adds a lot of much needed type safety, and also avoids ambiguity if you want the key and the values to be the same types (overloaded[]'s wont compile and etc)
You have to store the strings in RAM, which can be a problem.
Map is a container class that is used to store the aggregate data... Its very easy to retreive the datas stored in it as it uses hash algorithm for retrieval.
map is a key value pair...The data can be retrieved with the corresponding key...
Here in this declaration below I'm defining that the key has to be integer(4 bytes) and data as the string value...
typedef map<INT32U,string> EventMapType;
I searched for the example program of using map in wikipedia... But i could not understand the example given over there..I need to know how the datas and keys are stored in the map and how it is retreived through the key...I am new to MFC...
Beata,
I just did a quick google and came up with http://erunways.com/c-using-the-standard-template-library-stl-map-example/ I won't just copy paste that code here... it's only about 50 lines.
I suggest you read through that code, and then compile and run it (as is). If you run into problems or just stuff that doesn't make sense to you, then ask specific questions here. K?
Cheers. Keith.
map does not use hashing. It can't, because the constraints do not require hashable keys. It is ordinarily implemented as a binary search tree, sorted by key. Thus, it requires keys be <-comparable
In contrast, C++0x will provide an unordered_map, which does use hashing.
If you want specific help, you should tell us what code you've tried so far, and which examples you don't understand.
the STL's map class allows you to store data by any type of key instead of simply by a numerical key, the way you must access an array or vector. So instead of having to compute a hash function and then access an array, you can just let the map class do it for you.
typedef map<INT32U,string> MyEventMapType;
MyEventMapType EventMapType;
Use below as reference code.
To Store values :
EventMapType[key1] = string1 ;
EventMapType[key2] = string2 ;
EventMapType[key3] = string3 ;
To check the value at key1 ...
if(EventMapType.find("key1") == EventMapType.end())
{
std::cout<<"string1 is not in the map!"<<endl;
}
For more read the documentation
Iterators can also be used as a general means for accessing the data stored in a map; you can use the basic technique from before of getting an iterator:
i want to see the number of appearance of words from some phrases.
My problem is that i can't use map to do this:
map[word] = appearnce++;
Instead i have a class that uses binary tree and behaves like a map, but i only have the method:
void insert(string, int);
Is there a way to counts the words apperances using this function?(because i can't find a way to increment the int for every different word) Or do I have to overload operator [] for the class? What should i do ?
Presumably you also have a way to retrieve data from your map-like structure (storing data does little good unless you can also retrieve it). The obvious method would be to retrieve the current value, increment it, and store the result (or store 1 if retrieving showed the value wasn't present previously).
I guess this is homework and you're learning about binary trees. In that case I would implement operator[] to return a reference to the existing value (and if no value exists, default construct a value, insert it, and return that. Obviously operator[] will be implemented quite similarly to your insert method.
can you edit "insert" function?
if you can, you can add static variable that count the appearnces inside the function