473,395 Members | 1,458 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Lots of string compares

Hello,

what is a efficient solution to compare a string against a lot of
possiblities?

Currently i am having a lot of

if (strcmp(checkme, "option1", strlen(checkme))) {
value = OPTION1;
}

is there an other option? Or can i (ab)use a map or something for this?
Only then i would have the problem of filling the map first on every
call (or use a global).

I am using the current setup to gather input from keyboard / remote and
network. So i can handle the commands on a central place.

Suggestions welcome

gr. Bas
Oct 22 '06 #1
8 1410
Bas Nedermeijer <ba*@tdlnx.student.utwente.nlwrote:
>Hello,
>what is a efficient solution to compare a string against a lot of
possiblities?
>Currently i am having a lot of
>if (strcmp(checkme, "option1", strlen(checkme))) {
value = OPTION1;
>is there an other option?
(I think there are at least two problems in the above line
of code, but...)

How do you know this is not efficient enough?

Yes, you could use a std::map, however if you don't otherwise
need the map data structure, strcmp() or similar works just fine.

Steve
Oct 22 '06 #2
Bas Nedermeijer <ba*@tdlnx.student.utwente.nlwrote:
what is a efficient solution to compare a string against a lot of
possiblities?

Currently i am having a lot of

if (strcmp(checkme, "option1", strlen(checkme))) {
value = OPTION1;
}

is there an other option? Or can i (ab)use a map or something for this?
Only then i would have the problem of filling the map first on every
call (or use a global).

I am using the current setup to gather input from keyboard / remote and
network. So i can handle the commands on a central place.

Suggestions welcome
Time to have FUN WITH FUNCTORS that fabulous game show in which you can
amaze your programmer friends with your esoteric knowledge. :-)

const char* opt[] = { "opt1", "opt2", "opt3" }; // continue as needed
enum options { opt1, opt2, opt3, numOpts };

// ignore what's behind the curtain, just enjoy how easy
// this is to use in the "find_option_for" function

struct c_str_equal_to :
unary_negate<binder1st<pointer_to_binary_function< const char*,
const char*, int >
{
c_str_equal_to( const char* value ) :
unary_negate<binder1st<pointer_to_binary_function< const char*,
const char*, int >( bind1st( ptr_fun( &strcmp ), value ) )
{ }
};

// in debug, we first make sure there are no programming mistakes
// returns the correct option for the string passed in

options find_option_for( const char* value ) {
assert( find_if( opt, opt + numOpts, c_str_equal_to( value ) ) !=
opt + numOpts );
return (options)distance( opt, find_if( opt, opt + numOpts,
c_str_equal_to( value ) ) );
}

int main() {
options value = find_option_for( "opt3" );
assert( value == opt3 );

char checkme [4];
strcpy( checkme, "opt2" );
value = find_option_for( checkme );
assert( value == opt2 );
}

Seriously though, maybe you should just put the "checkme" value into a
std::string and use it directly instead of converting it to an enum (or
whatever type 'value' is.)

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer*have anyone to discuss your doubts with,
nor any ability to discuss them.
Oct 23 '06 #3
On Mon, 23 Oct 2006 01:41:18 +0200, Bas Nedermeijer wrote:
>what is a efficient solution to compare a string against a lot of
possiblities?
More details would be helpful.
>Currently i am having a lot of

if (strcmp(checkme, "option1", strlen(checkme))) {
you probably mean strncmp here
> value = OPTION1;
}
is there an other option?
In general strcmp (and in you example also strncmp) is slower than the
comparison with a string class that stores the actual length of the
string. operator== of such a string class might be implemented as
(buf is the internal character buffer):

friend inline
bool operator== (const string& left, const string& right) {
return left.length() == right.length()
&& *(left.buf) == *(right.buf)
&& strcmp (left.buf, right.buf) == 0;
}

When the actual length is stored in the string class then
string::length() is fast and not-equal strings are detected without a
call to strcmp(). It depends on the string implementation.

Best wishes,
Roland Pibinger
Oct 23 '06 #4
In article <45**************@news.utanet.at>,
Roland Pibinger <rp*****@yahoo.comwrote:
>On Mon, 23 Oct 2006 01:41:18 +0200, Bas Nedermeijer wrote:
>>what is a efficient solution to compare a string against a lot of
possiblities?

More details would be helpful.
>>Currently i am having a lot of

if (strcmp(checkme, "option1", strlen(checkme))) {

you probably mean strncmp here
>> value = OPTION1;
}
is there an other option?

In general strcmp (and in you example also strncmp) is slower than the
comparison with a string class that stores the actual length of the
string. operator== of such a string class might be implemented as
(buf is the internal character buffer):

friend inline
bool operator== (const string& left, const string& right) {
return left.length() == right.length()
&& *(left.buf) == *(right.buf)
&& strcmp (left.buf, right.buf) == 0;
}

When the actual length is stored in the string class then
string::length() is fast and not-equal strings are detected without a
call to strcmp(). It depends on the string implementation.
For arbitrary strings this is probably so.
When not arbitrary, may not be so.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Oct 23 '06 #5
Bas Nedermeijer posted:
what is a efficient solution to compare a string against a lot of
possiblities?
Depends if you know for sure that it must match one of the strings exactly.
If it must match, then all you need do is pick out a character index that's
unique in every string. For instance, if it must match one of the
following:

ardvard
arduous
ancestry
armadillo

, then we can single out the 4th character becauses it's unique to each
one:

switch(str[3])
{
case 'v': ...

case 'u': ...

case 'e': ...

case 'a': ...
}
(There might be the slight problem of reading past the end of a string such
as "a").

If you're not sure whether they'll match, then one possible solution would
be strcmp, although I'm not sure how efficent that will be if executed
multiple times. Perhaps you should code it yourself:

for( ; *p; ++p)
{
if ('a' == *p) CheckForArdvark();
if ('b' == *p) CheckForBaracuda();
}

--

Frederick Gotham
Oct 23 '06 #6

"Bas Nedermeijer" <ba*@tdlnx.student.utwente.nlwrote in message
news:eh**********@netlx020.civ.utwente.nl...
Hello,

what is a efficient solution to compare a string against a lot of
possiblities?

create a code generator which compares single characters via a switch
statement.
I call this a string tree -- it can be done dynamically or via generated
code.
e.g. if I have to fixed strings "aa" bb" to compare against the generated
code would look like:

switch (p[0])
{ default:
return ~0;
case 'a':
switch (p[1])
{ default:
return ~0;
case 'a':
return eID_AA;
}
break;
case 'b':
switch (p[1])
{ default:
return ~0;
case 'b':
return eID_BB;
}
}
This is very fast.
Finding a string depends only on the lenght of the string -- not of the
number of strings available for comparision.

Oct 24 '06 #7
Frank Puck posted:
return ~0;

What's the ~0 for?

On Two's complement, it will yield -1.

On One's complement, it will yield negative zero.

On Sign-magnitude, it will yield INT_MIN.

So what exactly do you what it to mean... ?

--

Frederick Gotham
Oct 24 '06 #8
In article <eh**********@netlx020.civ.utwente.nl>,
Bas Nedermeijer <ba*@tdlnx.student.utwente.nlwrote:
>Hello,

what is a efficient solution to compare a string against a lot of
possiblities?

Currently i am having a lot of

if (strcmp(checkme, "option1", strlen(checkme))) {
value = OPTION1;
}

is there an other option? Or can i (ab)use a map or something for this?
Only then i would have the problem of filling the map first on every
call (or use a global).
A C++ answer: Yes, use a map.

From what you hint, you have a number of known possible options:
"option1", "option2", ... "optionN"
You want to check the input against the list of known option to do something:

So:

First set up your map at start up. Once and only once:

std::map<std::string, value_typetheOptionMap;
map[std::string("option1")] = OPTION1;
map[std::string("option2")] = OPTION2;
....
map[std::string("optionN")] = OPTIONN;

// do whatever else initialisation you want to do.

// main loop:

std::string checkme = getInput();

// If checkme is always in the map, you can use:
value = theOptionMap[checkme];

// if not try:

std::map<std::string, value_type>::const_iterator iter = theOptionMap.find(checkme);
if( iter != theOptionMap.end() )
{
value = *iter;
}
else
{
// do whatever for an illegal option

}

The quality of this solution:

1- Easy to read, maintain, implement, expand, debug

2- Fast:
This is fast because the std::map keep the keys in sorted
order. Finding an option runs in logarithmic time. so instead of
comparing in average N/2 strings before finding the right one, you
only need to compare log(N). This is a huge gain if N is large.

Hope this helps
Yan

Oct 25 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: AlexS | last post by:
Hi, I wonder if anybody can comment if what I see is normal in FW 1.1 and how to avoid this. I have .Net assembly, which creates literally thousands of temporary strings and other objects...
24
by: ineedyourluvin1 | last post by:
Why does this reverse the string ? Sorry about using namespace std ; It made it easier to read :-) Thanks #include<iostream> using namespace std ; void rev_str( char* str ) {
2
by: Tom | last post by:
Hi, Our development team is adding DB2 8.1 compatibility to our existing application which currently supports SQLServer 2000. Our code is written to take advantage of SQLServer's ability to ...
6
by: Chris Simmons | last post by:
I know that a String is immutable, but I don't understand why this piece of code fails in nUnit: // BEGIN CODE using System; class Test { public static void Main( String args )
25
by: Dan Stromberg | last post by:
Hi folks. Python appears to have a good sort method, but when sorting array elements that are very large, and hence have very expensive compares, is there some sort of already-available sort...
94
by: smnoff | last post by:
I have searched the internet for malloc and dynamic malloc; however, I still don't know or readily see what is general way to allocate memory to char * variable that I want to assign the substring...
10
by: steve.lorimer | last post by:
I'm looking for a pre-processor command that will allow me to resolve const strings into const char literals at compile time. Looking at the code below, I can take 5 characters and create a...
9
by: chutsu | last post by:
hi I got a simple program, and I was wondering how do you check if the string in an array = a string. For example if I put "APPLE" in array Array then how can I check it with a if statement. if...
1
by: rnakawat | last post by:
I seem to have a problem using the preceding:: on substrings of the value. I'll try to explain with an example: Let's say I had a XML that look like: <Root> <Row> <Cell Name="Street"...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.