在c ++中搜索字符串对象数组的最有效方法?

时间:2014-04-10 17:06:30

标签: c++ arrays string search cstring

我一直在寻找关于这个主题的更多信息,似乎无法找到我正在寻找的答案,所以我希望你能提供帮助!

我正在研究的部分工作是编写一个搜索字符串数组(地址簿)的程序,如果找到完整匹配或部分匹配则返回匹配项。我能够使用C-Strings数组轻松地完成它,strstr()函数通过for循环运行,并将指针设置为将用户输入关键字运行到数组中的结果(见下文)。

我的问题是,如果有的话,我将如何利用String对象?我还需要考虑有多个可能的匹配。这也是最有效的方法吗?我已经提交了我的工作版本,我只是很好奇其他一些方法来完成同样的任务!

#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;
} 

正如你所知,我喜欢恐怖片:)

2 个答案:

答案 0 :(得分:2)

您确实需要将每个字符串分解为可排序的组件。如果您还不了解结构,可以使用更多数组。这将允许您构建“索引”表,以加快搜索速度。

最有效的方法是确定数据的数量和数据的组织。

对于小型数据集,不同搜索方法之间的时差通常可以忽略不计 - 程序中的某些其他项目需要更长时间(例如输入或输出)。

对于字符串数据,大部分时间用于将一个字符串的每个字符与另一个字符串进行比较。其他操作,例如移动指数,可以忽略不计。

由于已经执行了搜索方法之间的比较,因此在网络上搜索“性能字符串搜索比较”。

答案 1 :(得分:2)

另一种方法是使用正则表达式进行字符串搜索。现在有a lot of info out there我只是提供一个简单的示例,您尝试将记录(地址)的子范围与word2Search匹配(我已经这样做了)硬编码以避免混乱的例子)。

我还使用(注释中已经提到的一种技术)一个预处理步骤,对数组进行排序。小心两件事:

  • 完成排序以启用快速搜索方法,即二进制搜索(在此处使用lower_bound upper_bound实现)

  • 如果您搜索的单词不在记录的开头,则排序记录没有意义,因为您无法找到有效范围(此处it ite)搜索(例如,如果你搜索数字,字符串的排序将在字符串之间的字典比较中完成,因此找到555之间不会有任何好处。以M J开头的字符串等等)

评论中的解释:

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;
}