Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Searching an Array for multiple items at specified locations

Status
Not open for further replies.

mcbrune

Programmer
Jul 23, 2001
7
US
I have a program that currently has ALOT of if/else if statements searching a char array for specified elements at known locations. For example, I am looking for chars 'a' and 'b' at location 0, 3 or 4, 6. I thought of using a case statement, but because of the two values, I didn't think this work. Any other hints or is if/else the only way?

Thanks in advance!
 
Well, you could do a switch on the variable you check the most values on.

Like,
Code:
char ch = charArray[location];
switch(location)
{
  case 0:
  case 3:
  case 4:
  case 6:
    if(ch == 'a' || ch == 'b')
    {
       ...
    };break;
  case 2:
  case 5:
    if(ch == 'c' || ch == 'd')
    {
       ...
    };break;
}
but if you really have a lot and all matches should result in the same handling, you could use a map, for example:
[code]
#include <map>
#include <string>
typedef std::map<int,std::string> Lookup;
...
{
  Lookup lookup;
  lookup[0]= "ab";
  lookup[2]= "cd";
  lookup[3]= "ab";
  lookup[4]= "ab";
  lookup[5]= "cd";
  lookup[6]= "ab";
}

// Then in the loop you'd check the contents of the map
// (It's assumed lookup has been passed to the function)
{
  ...
  Lookup::const_iterator i = lookup.find(location);
  if (i!=lookup.end())
  {
    if ((*i).find(charArray[location])!=std::string::npos)
    {
      // Do something
    }
  }
  ...
}


/Per

&quot;It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure.&quot;
 
Another way more using the ++ part of C++ can be useful if the charArray is really big and you have a lot of characters to test against, and/or you want to modify it without dig into the (growing?) if..else statement.

Make a small framework that lets you do the checking in a generic fashion, at one point you define what's done and when, while the checking itself is quite generic.

Code:
// A Doer is a class that does something :-)
class Doer
{
	virtual ~Doer() {}
	virtual void doSomething()=0;
};

class DoThis : public Doer
{
	virtual ~DoThis() {}
	virtual void doSomething() { ... }
};

class DoThat : public Doer
{
	virtual ~DoThat() {}
	virtual void doSomething() { ... }
};

// Map a doer to a string
typedef std::pair<std::string, Doer*> StringDoer;
// Map StringDoers to locations
typedef std::map<int, StringDoer> Lookup;

	// At some point define what location & char relate to a certain Doer
	...
	Lookup lookup;
	DoThis doThis;
	DoThat doThat;

	lookup[0] = StringDoer("ab", &doThis);
	lookup[3] = StringDoer("ab", &doThis);
	lookup[4] = StringDoer("ab", &doThis);
	lookup[6] = StringDoer("ab", &doThis);

	lookup[2] = StringDoer("cd", &doThat);
	lookup[5] = StringDoer("cd", &doThat);
	...
	// The checking is unaffected by the size of things...
	Lookup::const_iterator i = lookup.find(location);
	if (i!=lookup.end())
	{
		if ((*i).second.first.find(charArray[location])!=std::string::npos)
		{
			// Call the doer for this location/char combination
			(*i).second.second->doSomething();      
		}
	}

/Per

&quot;It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure.&quot;
 
Hows about this...
(I've been doing PERL lately so forgive the syntax errors)

boolean find( char *theString)
{
int size = 0;
char *temp = theString;
int nChars = 2;
char theChars[] = ('a', 'b');
int nSpots = 2;
int theSpots[][nChars] = ((0,3), (4,6));

while (*temp++)
++size;

for (i=0; i<nSpots; ++i) {
found = 0;
for (j=0; j<nChars; ++j) {
if (theSpots[j] >= size)
break;
if (theString[ theSpots[j]]==theChars[j])
++found;
}
if (found==nChars)
return TRUE;
}

return FALSE;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top