Question

I've been searching for some more information on this topic, and can't seem to find the answer I'm looking for, so I hope you can help!

Part of an assignment I'm working on is to write a program that searches an array of strings (address book), and returns matches if a full or partial match is found. I'm able to do it easily using an array of C-Strings, with the strstr() function running through a for loop and setting the pointer to the result of running the user input keyword into the array (see below).

My question is, how would I be able to do this, if at all, utilizing String objects? I also need to take into consideration there being more than one possible match. Is this the most efficient way of working this program out as well? I've already submitted my working version, I'm just curious as to some other methods to accomplish the same task!

#include <iostream>
#include <cstring>
using namespace std;

int main()
{

  bool isFound = false;         // Flag to indicate whether contact is found
  const int SIZE = 11;          // Size of contacts array
  const int MAX = 50;           // Maximum characters per row
  char contacts[SIZE][MAX] = { 
                                "Jig Sawyer, 555-1223",
                                "Michael Meyers, 555-0097",
                                "Jason Vorhees, 555-8787",
                                "Norman Bates, 555-1212",
                                "Count Dracula, 555-8878",
                                "Samara Moran, 555-0998",
                                "Hannibal Lector, 555-8712",
                                "Freddy Krueger, 555-7676",
                                "Leather Face, 555-9037",
                                "George H Bush, 555-4939",
                                "George W Bush, 555-2783"
                              };
  char *ptr = NULL;             // Pointer to search string within contacts
  char input[MAX];              // User search input string


  // Get the user input
  cout << "Please enter a contact to lookup in the address book: ";
  cin.getline(input,MAX);

  // Lookup contact(s)
  for (int i=0; i<SIZE; i++)
  {
    ptr = strstr(contacts[i], input);
    if (ptr != NULL)
      {
        cout << contacts[i] << endl;
        isFound = true;
      }
  }

  // Display error message if no matches found
  if (!contactFound)
    cout << "No contacts found." << endl;

  return 0;
} 

As you can tell, I like horror movies :)

Was it helpful?

Solution

An alternative would be to use regular expressions for string search. Now there's a lot of info out there and I'll just be providing a simple example where you try to match a subrange of the records (addresses) with a word2Search (which I've hardcoded to avoid cluttering the example).

I'm also using (a technique already mentioned in the comments) a preprocessing step where the array is sorted. Beware of two things :

  • The sorting is done to enable a fast searching method, ie binary search (implemented with lower_bound upper_bound here)

  • If the word you are searching is not at the beginning of a record, there is no point in sorting the records since you won't be able to find a valid range (here it ite) to search into (eg if you search for the numbers, the sorting of the string would be done in lexicographical comparison between strings, so it wouldn't be any good for locating 555 among strings beginning with M J and so on)

Explanation in the comments:

int main()
{
    // 1. Minor change - an array of strings is used
    string contacts[] = { 
        "Jig Sawyer, 555-1223",
        "Michael Meyers, 555-0097",
        "Jason Vorhees, 555-8787",
        "Norman Bates, 555-1212",
        "Count Dracula, 555-8878",
        "Samara Moran, 555-0998",
        "Hannibal Lector, 555-8712",
        "Freddy Krueger, 555-7676",
        "Leather Face, 555-9037",
        "George H Bush, 555-4939",
        "George W Bush, 555-2783"
    };
    // 2. The array is sorted to allow for binary search
    sort(begin(contacts), end(contacts));
    // 3. Example hard coded a word to search 
    string word2Search = "George";
    // 4. A regular expression is formed out of the target word
    regex expr(word2Search);
    // 5. Upper and lower bounds are set for the search
    char f = word2Search[0];
    std::string val1(1, f);
    std::string val2(1, ++f);
    // 6. Perform the search using regular expressions
    for (auto it(lower_bound(begin(contacts), end(contacts), val1)), 
        ite(lower_bound(begin(contacts), end(contacts), val2)); it != ite; ++it)
    {
        if (regex_search(it->begin(), it->end(), expr)) {
            cout << *it << endl;
        }
    }

    return 0;
}

OTHER TIPS

You really need to break each string into sortable components. If you don't know about structures yet, you can use more arrays. This would allow you to build "index" tables that would speed up the search.

The most efficient method determines on the quantity of the data and the organization of the data.

For small sets of data, the time difference between the different search methods is usually negligible -- some other item in your program will take longer (such as input or output).

With string data, most of the time is spent comparing each character of one string to another. The other operations, such as moving indices around, are negligible.

Since the comparison between search methods has already been performed, search the web for "Performance string searching comparing".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top