Originally posted by: kavitha
void main(){
cout << "Enter a string"<< endl;
//now use switch statement
switch(strValue)
}
I guess using string class in c++ solves the problem without any mapping.
#include <string>
#include <iostream>
using namespace std;
string strValue;
cin >> strValue;
{
case "Value X":
DoThis();
break;
case "Value Y":
DoThat();
break;
case "Value Z";
DoSomethingElse();
break;
default:
DontKnowWhatToDo();
break;
}
Reply
Originally posted by: Yaniv D
This code does not conform to the old
Keep It Simple. St..id rule
its like cleaning you room by putting all dirt under the
carpet.
Reply
Originally posted by: Steffen Offermann
BTW: I use a similar approach in my code when I have many strings, since I find it much more elegant and easier to read than the strcmp() method. This is what I do (although usually within a class):
enum E_Key
E_Key getKey (const char * pString)
for (size_t i=0; i < sizeof(tab) / sizeof(tab[0]); i++ )
Thus I can always write my switch statements like this:
case c_keyName: // ...
case c_keyPath: // ...
Regards,
It's hard to believe how childish people can be. Those who post articles and code to this site mean to be helpful to others. I really cannot see an excuse for all this bashing.
{
c_keyUnknown,
c_keyName,
c_keyPath,
...
};
{
struct
{
E_Key m_key;
char * m_pString;
}
tab [] =
{
{c_keyName, "Name"},
{c_keyPath, "Path"},
...
} ;
{
if ( 0 == stricmp (tab [i].m_pString, pString) )
return tab [i].m_key;
}
return c_keyUnknown;
}
switch ( getKey (strKey) )
{
case c_keyUnkown: // ...
break;
break;
break;
}
Steffen
Originally posted by: John McNeill
I've been trying to learn C++ on my own. I've done a lot of programming in Basic and use a simple bubble sort to sort string arrays. Why can't I use the same concept in C++. Why can't I assign the value of an element in an array such as sentence[][] to an array like temp[]?
I'd appreciate any help.
John McNeill
ReplyOriginally posted by: NMTop40
void myFunc( const char * str )
if ( it != myMap().end() )
// see who said I needed a switch at all?
typedef void (pfn)(); // for example
typedef std::map< std::string, pfn* > pfnMap;
pfnMap& myMap(); // gets single instance of this map
{
pfnMap::iterator it = myMap().find( str );
{
(it->second)();
}
else
{
RunDefaultFunction();
}
}
Originally posted by: Kenny
although STL does not define what search algorithm is
This gives each string lookup to be bouned by O(log(n)).
the if-else-strcmp approach gives no such guarantee. It's
Consequently, the proposed approach is generally faster
On a personal note:
For large number of strings, the proposed method is
more efficient than if-else-strcmp approach because
it takes advantage of the inherent search properties
of the map to implement a psuedo-hash function.
implemented in a map, the most general case is a binary
tree, and most likely is a red-black tree (MS imp does
that, and I can't imagine why SGI imp wouldn't).
Then you switch on the enum returned, which, given that
it's sequential, should be compiled into a lookup table,
and that should be a O(1) operation.
all based on the order of your if-else chain. Your worst
case scenario is O(n). There is a case where you can
hand-optimize your code to put the more commonly used
strings at the beginning of the chain, but that's just
unstructured.
at run-time than the if-else-strcmp method. It can even
be improved to use a hash_map. Checking 3 strings is
inconsequential, however, 20 strings is a different
story -- and that will typically be the case for such
applications as parser.
it's sad that some of the UNIX advocates did not see the
code in this light, I thought we'd be better than that.
Reply
Originally posted by: aaron
i only wish it would fall of the face of the earth. that's all.
ReplyOriginally posted by: Chandima
This code tries to make something simple by making it complex. Who is going to use this? Nobody. Because, it is much easier and faster and familiar to use strcmp than this method.
Just a waste of time.
ReplyOriginally posted by: Chandima
I am not trying to blame the author for writing this code. But some readers may have wrong impressions after looking at this code.
I have seen one comment from a reader saying that when handling thousands of strings this method will be faster than strcmp () method.
That is completely untrue. Becuase, the fastest way to compare a string is to use the strcmp () method. There is no other way which is faster than this. Just using a string case statement in a switch doesn't make it faster. After all the compiler has to convert it to machine code string comparison commands. Where the strcmp () will be converted to a very simple set of machine instructions (or may be a single instruction) where as the mapping statements will result in several more machine instructions which is obviously slower.
However, if you want to handle thousands of strings and compare them the best way is to use arrays or much better to use a dictionary. Using a dictionary it will be much much faster when to compare thousands of strings.
If anyone wants to know how to use a string dictionary to compare thousands or millions of strings, I can send some sample code if you send me a mail.
Originally posted by: Sergei Yurchenko
#include <string>
class A {
void main()
Faced a problem today when I was working on the design of a dozen of classes.
There I wanted to have a new type defined in each class with "enum" and a
map that converts string value given to it, to this new type. Here's what
I've come up with so far, if anyone is interested (of course, this
is not one of my classes, I made this just to show the idea):
#include <map>
public:
A() {
if(the_type_map.size() == 0)
{
the_type_map["type1"] = A_TYPE_1;
the_type_map["type2"] = A_TYPE_2;
}
}
enum AType {
A_TYPE_UNDEFINED,
A_TYPE_1,
A_TYPE_2
};
AType the_type;
AType InitializeType(std::string s)
{
std::map< std::string, AType >::const_iterator it;
the_type = ((it = the_type_map.find(s)) != the_type_map.end()) ? it->second : A_TYPE_UNDEFINED;
}
private:
static std::map< std::string, AType > the_type_map;
};
std::map < std::string, A::AType > A::the_type_map;
{
A a;
a.InitializeType("type1");
}