C语言,哈希表,单词排序
- 格式:docx
- 大小:16.23 KB
- 文档页数:4
char word[WORDLEN];
int num;
hashele* next;
};
hashele* hashform[KEYMAX]; //定义散转表,每个数组元素为相同关键码值的一系列单词对应的结构体形成的链表的头指针
unsigned int worfkey(const char* word) //计算采集到的新单词的关键码值
{
struct hashele **aa=(hashele **)a; //强制类型转换,将qsort默认的无类型指针转换为结构体指针
struct hashele **bb=(hashele **)b;
if(((*aa)->num)==((*bb)->num)) //当单词出现次数相等,则按字典顺序进行排序
scanf("%s%*c",&fpname);
if((fp=fopen(fpname,"r"))==NULL) //打开文件,将fp指针指向文件的第一个字符
{
printf("fail to open the file\n",fpname);
exit(0);
}
state=OUTWORD; //采集状态最初为在单词外
qsort(sort,numofsort,sizeof(sort[0]),comp); //调用qsort函数进行排序
printf("please input the name of the file you want to output to\n");
scanf("%s%*c",frname);
fr=fopen(frname,"w"); //定义输出文件指针,准备将结果写入用户指定的文件
if(fr==NULL) //若文件打开失败,提醒用户相关信息
{
printf("fail to establish the result file\n");
return 0;
}
else
printf("the result file has been established\n");
for(i=0;i<numofsort;i++) //遍历临时数组进行写入
#define INWORD 1 //此时文件指针指在单词之内
#define KEYMAX 9973 //定义哈希表数组(即散列表)的最大长度为9973,即单词所对应的关键码值有9973个,形成9973元素的散列表
int toatalnum; //对单词总数(不重复)加以计数
struct hashele //定义结构体,形成链表
strcpy(newele->word, word); //给新表元的word赋值
newele->next = hashform[place]; //将新表元插入到链表的最前面,使插入操作最简化
hashform[place] = newele;
toatalnum++; //单词总数加1
}
int comp(const void*a ,const void *b) //为主函数中调用的qsort快排函数定义比较函数
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<ctype.h>
#include<stdlib.h>
#define WORDLEN 40 //设置单词字母最多为40个
#define OUTWORD 0 //为了增强程序可读性,进行宏定义,表示此时文件指针指在单词之外
int k=0;
while((ch=fgetc(fp))!=EOF)
{
if(isalpha(ch)||(ch=='\'')&&(state==INWORD)) //读到单词或者“’”则认为此时为在单词中
{
state=INWORD;
if(ch>='A'&&ch<='Z') //大写转小写
ch=ch+('a'-'A');
for(i = 0; i < KEYMAX; ++i) //遍历散列表,将所有单词对应的结构体放入临时指针数组里
{
if(hashform[i])
{
hashele* p = hashform[i];
while(p)
{
*(sort+j)=p;
j++;
p=p->next;
}
}
}
int numofsort=j;
k=0;
}
}
fclose(fp);
fr=fopen(frname,"w"); //打开用户指定的文件,准备写入统计结果
hashele *(*sort); //定义临时指针数组用于存放所有非重复单词,便于下一步的排序
sort=(hashele **)calloc(toatalnum,sizeof(hashele **));
{
const signed char *p = (const signed char*)word; //定义临时指针对字符串进行计算,以保留原单词信息
unsigned int key = *p;
if(key)
{
for(p += 1; *p != '\0'; ++p) //当遍历到空元素,关键码值的计算结束
*(word+k)=ch; //将采集到的单词放在临时字符数组中
k++;
}ቤተ መጻሕፍቲ ባይዱ
else
if(!isalpha(ch)&&state==INWORD)
{
state=OUTWORD; //如果原状态在单词中,下一个为非字母,则状态变为在单词外,一个单词的采集结束
*(word+k)='\0';
insertaword(word); //将单词插入散列表
bool state=0; //定义bool变量表示采集单词的状态
int ch,i=0,j=0;
char fpname[40],frname[40],word[WORDLEN];
printf("please input the name of the file you want to operate:\n");
key = (key << 5) - key + *p; //定义哈希函数,将单词映射到散列表里
key=key%KEYMAX;
}
return key; //返回该单词对应的关键码值
}
void insertaword(const char* word)
{
unsigned int place = worfkey(word); //调用关键码值计算函数得到单词对应的关键码值
{
fprintf(fr,"%-18s:\t",sort[i]->word);
fprintf(fr,"%d\n",sort[i]->num);
}
printf("the result file has been finished\n");
fclose(fr);
}
return(strcmp((*aa)->word,(*bb)->word)>0?1:-1);
else
return(((*aa)->num)>((*bb)->num)?1:-1); //如果单词出现次数不相等,则按出现次数排列
}
int main()
{
FILE *fp; //定义输入文件的指针
FILE *fr; //定义输出文件的指针
{
p->num++;
return ;
}
p = p->next; //遇到相同单词前继续遍历
}
hashele* newele = (hashele*)malloc(sizeof(hashele)); //在该关键码值的链表中没有找到该单词,则准备插入
newele->num=1; //新表元计数变量为1
hashele* p = hashform[place]; //找到该关键码值的链表头指针在数组中的位置,定义临时指针进行遍历操作
while(p) //遍历该单词的关键码值对应的链表,看是否有相同单词
{
if(strcmp(p->word, word) == 0) //如果对应的单词相同则该结构体的计数变量加一