/*文件命名:search.c
欢迎大家指正
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define N 10000000
#define STEP 3
#define LOOP 500000
// for string search
#define STR_LEN 10
#define CHAR_SIZE 10
// for hash table
#define HASH_SIZE (N/100+1)
struct node {
char szKeyword[STR_LEN];
struct node *next;
};
int a[N];
int g_nMax=0;
char g_szKey[N][STR_LEN];
struct node *hashHead[HASH_SIZE];
// 给 qsort 使用
int str_compare(const void *s1, const void *s2)
{
return *(const char *)s1-*(const char *)s2;
}
// String 使用的 binary search
int str_binary_search(int min, int max, char *s)
{
int mid=0,n;
if (min > max) return -1;
mid = min + (max - min) / 2;
n = strcmp(s,g_szKey[mid]);
if (n == 0)
return mid;
else if (n < 0)
return binary_search(min,mid-1,s);
else
return binary_search(mid+1,max,s);
} // int str_binary_search(int min, int max, char *s)
// 数字使用的 binary search
int binary_search(int min, int max, int n)
{
int mid=0;
if (min > max) return -1;
mid = min + (max - min) / 2;
if (a[mid] == n)
return n;
else if (n < a[mid])
return binary_search(min,mid-1,n);
else
return binary_search(mid+1,max,n);
} // int bsearch(int min, int max, int n)
int hash_function(char *s) {
int i,n;
unsigned int sum=0;
if (s == NULL)
return -1;
n = strlen(s);
for (i=0;i<n;i++)
sum = (sum << 7) + s[i];
return sum % HASH_SIZE;
} // end of hash_function
int main(void)
{
time_t t=0;
int i,j,k,n=0;
int nLen=0;
clock_t begin=0,end=0;
char szSearch[STR_LEN];
struct node *ptr=NULL;
////////////////////////////
// Build an array (increasing)
////////////////////////////
time(&t);
srand(t);
for (i=0;i<N;i++) {
a[i] = g_nMax + 1 + (rand()%STEP);
g_nMax = a[i];
} // end of for (i=0;i<N;i++)
n = rand() % (g_nMax + 1);
////////////////////////////
// Sequential search
// find n in the array
////////////////////////////
begin = clock();
for (i=0;i<N;i++) {
if (a[i] == n) {
printf("%d 找到了\n",n);
break;
}
}
if (i == N)
printf("%d 没找到\n",n);
end = clock();
printf("Sequential search \t花费时间=%f\n",(float)(end-begin)/CLOCKS_PER_SEC);
/////////////////////////////
// Binary search
/////////////////////////////
begin = clock();
for (i=0;i<LOOP;i++) {
binary_search(0,N-1,n);
}
end = clock();
printf("Binary search \t\t花费时间=%.8lf\n",(double)(end-begin)/LOOP/CLOCKS_PER_SEC);
/////////////////////////////
// Build random string array
// 建立 N 个 长度 5 ~ 9 的 strings, 存在 g_szKey[i] 里面
/////////////////////////////
for (i=0;i<N;i++) {
// 长度为 5,6,7,8,9
nLen = rand() % 5 + 5; // 5,6,7,8,9
for (j=0;j<nLen;j++)
g_szKey[i][j] = (rand() % CHAR_SIZE) + 'A'; // A,B,C...
g_szKey[i][j] = '\0';
}
// 把 g_szKey 排序排好 (binary search 会用到)
qsort(g_szKey,N,STR_LEN,str_compare);
// Randomly generate szSearch, 产生等等要搜索的 szSearch
nLen = rand() % 5 + 5;
for (i=0;i<nLen;i++)
szSearch[i] = (rand() % CHAR_SIZE) + 'A'; // A,B,C...
szSearch[i] = '\0';
////////////////////////////
// Sequential search
// find szSearch in the array g_szKey
////////////////////////////
begin = clock();
for (i=0;i<N;i++) {
if (strcmp(g_szKey[i],szSearch) == 0) {
printf("%s 找到了\n",szSearch);
break;
}
}
if (i == N)
printf("%s 没找到\n",szSearch);
end = clock();
printf("Sequential search \t花费时间=%f\n",(float)(end-begin)/CLOCKS_PER_SEC);
/////////////////////////////
// Binary search
// find szSearch in the array g_szKey
/////////////////////////////
begin = clock();
for (i=0;i<LOOP;i++) {
str_binary_search(0,N-1,szSearch);
}
end = clock();
printf("Binary search \t\t花费时间=%.8lf\n",(double)(end-begin)/LOOP/CLOCKS_PER_SEC);
/////////////////////////////
// Build hash table
/////////////////////////////
memset(hashHead,0,sizeof(struct node *)*HASH_SIZE);
for (i=0;i<N;i++) { // insert into hash table
n = hash_function(g_szKey[i]);
if ((ptr = (struct node *)malloc(sizeof(struct node))) == NULL) {
printf("Malloc failed in %d\n",__LINE__);
return;
}
strncpy(ptr->szKeyword,g_szKey[i],STR_LEN-1);
ptr->szKeyword[STR_LEN-1] = '\0';
ptr->next = hashHead[n];
hashHead[n] = ptr;
} // end of for (i=0;i<N;i++)
/////////////////////////////
// Hash table search
// find szSearch in the hash table
/////////////////////////////
begin = clock();
for (i=0;i<LOOP;i++) {
n = hash_function(szSearch);
ptr = hashHead[n];
while(ptr != NULL) {
if (strcmp(ptr->szKeyword,szSearch) == 0)
break;
ptr = ptr->next;
}
}
end = clock();
printf("Hash table search \t花费时间=%.8lf\n",(double)(end-begin)/LOOP/CLOCKS_PER_SEC);
return 0;
} // end of main()