单词查找(综合版)

从标准输入中读入一个英文单词及查找方式,在一个给定的英文常用单词字典文件dictionary3000.txt中查找该单词,返回查找结果(查找到返回1,否则返回0)和查找过程中单词的比较次数。查找前,先将所有字典中单词读入至一个单词表(数组)中,然后按要求进行查找。字典中单词总数不超过3500,单词中的字符都是英文小写字母,并已按字典序排好序(可从课件下载区下载该字典文件)。字典中的单词和待查找单词的字符个数不超过20

查找方式说明:查找方式以1~4数字表示,每个数字含义如下:

1:在单词表中以顺序查找方式查找,因为单词表已排好序,遇到相同的或第一个比待查找的单词大的单词,就要终止查找

2:在单词表中以折半查找方式查找;

3:在单词表中通过索引表来获取单词查找范围,并在该查找范围中以折半方式查找。索引表构建方式为:以26个英文字母为头字母的单词在字典中的起始位置和单词个数来构建索引表,如:

字母

起始位置

单词个数

a

0

248

b

248

167

该索引表表明以字母a开头的单词在单词表中的开始下标位置为0,单词个数为248

4:按下面给定的hash函数为字典中单词构造一个hash表,hash冲突时按字典序依次存放单词。hash查找遇到冲突时,采用链地址法处理,在冲突链表中找到或未找到(遇到第一个比待查找的单词大的单词或链表结束)便结束查找

/* compute hash value for string */

#define NHASH  3001

#define MULT  37

unsigned int hash(char *str)

{

       unsigned int h=0;

       char *p;

 

       for(p=str; *p!='\0'; p++)

              h = MULT*h + *p;

       return h % NHASH;

}

提示:hash表可以构建成指针数组,hash冲突的单词形成一有序链表。

【输入形式】

单词字典文件dictionary3000.txt存放在当前目录下,待查找单词和查找方式从标准输入读取。待查找单词只包含英文小写字母,与表示查找方式的整数之间以一个空格分隔。

【输出形式】

将查找结果和单词比较次数输出到标准输出上,两整数之间以一个空格分隔。
【样例输入与输出】
单词字典文件dictionary3000.txt与课件下载中提供的相同,下面两列中,左侧为待查找单词与查找方式,右侧为对应的输出结果:

wins 1                              0 3314

wins 2                              0 12

wins 3                              0 7

wins 4                              0 2

yes 1                               1 3357

yes 2                               1 10

yes 3                               1 4

yes 4                               1 1
【样例说明】

wins在单词字典中不存在,4种查找方式都输出结果0,顺序查找、折半查找、索引查找和hash查找的单词比较次数分别为:3314、12、7和2次(wins的hash位置与字典中physics和suggest相同)。

yes在单词字典中存在,4种查找方式都输出结果1,顺序查找、折半查找、索引查找和hash查找的单词比较次数分别为:3357、10、4和1。


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct word_list{
    char word[26];
};
struct word_list word_block[3510];
struct index{
	char alpha;
	int start;
	int all;
};
struct index index_list[26];
#define NHASH  3001
#define MULT  37
unsigned int hash(char *str)
{
       unsigned int h=0;
       char *p;
		for(p=str; *p!='\0'; p++)
			h = MULT*h + *p;


       return h % NHASH;


}
typedef struct node{
    char word[26];
    struct node *link;
}LNode, *LinkList;
void order_search(struct word_list word_block[], char obj[]);
void bisearch(struct word_list word_block[], char obj[] );
void index_search(struct index index_list[], char obj[] );
void insert(LinkList list, char temp[]);


int total = 0;
int main()
{
    FILE *in;
    in = fopen("dictionary3000.txt","r");
    int i = 0, method, times = 0, loop = 0;  /*i is the total number of all words, times marks times of comparing in search*/
    char temp[26], obj[26];
    char head_letter = 'a';
    int j = 1, all1 = 0;
    int hash_value;
	LinkList list = NULL, p;
    LinkList hash_list[3002];
    for(loop = 0; loop<3002; loop++)
    {
    	list = (LinkList)malloc(sizeof(LNode)); 
    	list->link = NULL;
    	hash_list[loop] = list;
	}


    
    for(loop=0; loop<26; loop++)
    {
    	index_list[loop].alpha = 'a' + loop;
    	index_list[loop].all = 0;
    	index_list[loop].start = 0;
	}
	index_list[0].alpha = 'a';
	index_list[0].start = 0;
    
    while( !feof(in) )
    {
        fscanf(in, "%s", &temp);
        strcpy(word_block[i].word, temp);
        
        index_list[temp[0]-'a'].all++;
        if( temp[0] != head_letter )
        {
        		head_letter++;
        		index_list[temp[0]-'a'].start = i;
		}
		
		hash_value = hash(temp);    /*计算出它的哈希值*/
		if( hash_list[hash_value]->link == NULL ) 
		{
			p = hash_list[hash_value];
			strcpy(p->word, temp);
			p->link = NULL;
		}
		else if( hash_list[hash_value]->link != NULL )   
		{
			insert(hash_list[hash_value], temp);
		}
		
        i++;
    }
    index_list['z'-'a'].all--;
   
    total = i-1;


    scanf("%s %d", &obj, &method);
    if( method == 1)  /*order search*/
    {
        order_search(word_block, obj);
    }
    else if(method ==2)
    {
    	bisearch(word_block, obj);
	}
	else if (method == 3)
	{
		index_search(index_list, obj);
	}
	else if(method == 4)
	{
		hash_value = hash(obj);
		p = hash_list[hash_value];   /*hash value is a head pointer*/
		times++;
		while( strcmp(p->word , obj) > 0  && p->link != NULL) 
		{
			p = p->link;
			times++;
		}
		if( strcmp(p->word , obj) == 0)
		{
			printf("1 %d\n", times);
		}
		else 
		{
			printf("0 %d\n", times+1);
		}
	
	}


    fclose(in);
    return 0;
}


void order_search(struct word_list word_block[], char obj[])
{
	int i = 0, times = 0;
	for(i = 0; i<=3500; i++ )
    {
        times++;
        if( strcmp(obj, word_block[i].word ) > 0 )
                continue;
            
        else if( strcmp(obj, word_block[i].word ) == 0 )
        {
			printf("1 %d\n", times);
            break;
        }
        else {
            printf("0 %d\n", times);
            break;
        }
    }
}
void bisearch( struct word_list word_block[], char obj[] )
{
    int low = 0, high = total-1, mid, times = 0, find = 0;
    while ( low<=high ){
       	times++;
        mid = (low + high)/2;
        if( strcmp( word_block[mid].word, obj ) ==0 )
        {
            printf("1 %d\n", times);
            find = 1;
            break;
        }
        else if( strcmp( word_block[mid].word, obj ) < 0)
        {
            low = mid + 1;
        }
        else 
        {
            high = mid - 1;
        }
    }
    if(find == 0)
    {
        printf("0 %d\n", times);
    }
}
void index_search( struct index index_list[], char obj[] )
{
	int low = index_list[obj[0]-'a'].start , high = low+index_list[obj[0]-'a'].all-1 , mid, times = 0, find = 0;
    while ( low<=high ){
 	times++;
        mid = (low + high)/2;
        if( strcmp( word_block[mid].word, obj ) ==0 )
        {
            printf("1 %d\n", times);
            find = 1;
            break;
        }
        else if( strcmp( word_block[mid].word, obj ) < 0)
        {
            low = mid + 1;
        }
        else 
        {
            high = mid - 1;
        }
    }
    if(find == 0)
    {
        printf("0 %d\n", times);
    }
}


void insert(LinkList list, char temp[])   /*大指针数组内的某个元素 是该链表的头结点*/
{
    LinkList p, r;
    r = list;  /*wei zhi zhen */
    while(r->link != NULL)
    {
        r = r->link;
    }
    p = (LinkList)malloc(sizeof(LNode));
    strcpy(p->word, temp);
    p->link = NULL;
    r->link = p;


}

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值