[英]Efficient way to search a string in an array of string in C. (Case insensitive)
我正在一个项目(用C实现)中,需要维护功能列表或关键字。 用户输入一个字符串。 我们需要在存储的字符串数组中对此字符串进行不区分大小写的搜索。 该列表当前包含100个字符串,并且可以添加新的字符串(每年约5个字符串)。
我想知道存储此数组并提高搜索效率的最佳方法。
当前实现的解决方案如下所示:(我尚未编译此代码。这只是一个代码片段。)
char **applist={ asdf , adgh, eftg , egty, ...}
char *user_input; // this string contains user entered string
int id;
switch(user_input[0])
{
case 'a':
case 'A':
switch(user_input[1]
{
case 's':
case 'S':
id=0
break;
case 'd':
case 'D':
id=1
break;
}
break;
case'e':
case'E':
switch(user_input[1])
{
case 'f':
case 'F':
id=2
break;
case 'g':
case 'G':
id=3
break;
}
break;
}
if(stricmp(user_input,applist[id]))
return id;
else
return -1;
在实际代码中,applist未排序。 随着新字符串添加到applist中,我需要一种有效的方法来存储此数组。
如果我存储按字母顺序排序的字符串,则每次添加新字符串时,我都必须手动查找新字符串的正确位置。 (在运行时编译代码之前,会将新字符串添加到applist中)
建议执行此操作的有效方法。
编辑:我当前的方法导致更长的代码,但它的效率。 但是此代码不容易维护。 我需要的是一个数据结构,该结构可以以与此相同的效率进行搜索,但是代码更小。 您建议的数据结构不应有额外的开销。 唯一的要求是有效的搜索。 以及一种在编译时轻松将元素添加到数据结构的方法。 在运行时排序不是我的要求,因为在编译时会添加新字符串(这是为了避免限制用户将任何新字符串添加到列表中)。
听起来这不是代码的性能关键,在这种情况下,我建议使用strcasestr进行字符串比较。 像这样存储关键字
char *applist[] = {"abc", "def", "geh"}
然后遍历它们,并将用户输入与strcasestr进行比较,如下所示
if (strlen(applist[id]) == strlen(user_input) &&
strcasestr(applist[id], user_input) != NULL)
return id;
与使用复杂的数据结构相比,此方法更加简洁和可维护。 如果确实关心性能,请首先实施此方法,进行一些时序测试,然后再确定是否需要更快的算法。
在搜索字符串时,可以使用的最佳数据结构是BST-二进制搜索树-http: //en.wikipedia.org/wiki/Binary_search_tree 。 在最坏的情况下搜索时间将只有O(log n)
比较, O(n)
当使用arrays
或lists
。
这是带有数字的示例代码(您可能必须使用字符串对其进行更改并使用strcmp
):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
typedef struct node {
int data;
struct node *left;
struct node *right;
} NODE;
NODE * newnode (int data)
{
NODE * n = NULL;
if (n = (NODE *) malloc (sizeof (NODE))) {
n->data = data;
n->right = n->left = NULL;
} else {
printf("Error: unable to allocate memory \n");
}
return n;
}
NODE * insert (NODE * head, int data)
{
NODE * n;
if (head == NULL)
return newnode(data);
if (head->data == data) {
printf("Info: attempting to add duplicate element : %d\n", data);
return head;
}
if (head->data < data)
head->right = insert(head->right, data);
else
head->left = insert(head->left, data);
return head;
}
void inorder(NODE * node)
{
if (node == NULL)
return;
inorder(node->left);
printf("%d ", node->data);
inorder(node->right);
return;
}
int lookup(NODE * head, int data)
{
if (head == NULL)
return 0;
if (head->data == data)
return 1;
if (head->data < data)
return lookup(head->right, data);
else
return lookup(head->left, data);
}
void search(NODE * head, int data)
{
if (lookup(head, data)) {
printf("found : %d \n", data);
} else {
printf("not found : %d \n", data);
}
return;
}
int main()
{
int sum = 35;
NODE * root = NULL;
root = insert(root, 20);
root = insert(root, 10);
root = insert(root, 22);
root = insert(root, 23);
root = insert(root, 24);
root = insert(root, 25);
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 60);
inorder(root); printf("\n");
search(root, 10);
search(root, 11);
search(root, 13);
search(root, 14);
return 0;
}
OTOH,草率的表格将为您提供恒定的搜索时间O(1) -http://en.wikipedia.org/wiki/Hash_table
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.