辅导C程序、辅导C编程、辅导计算机C语言

- 首页 >> C/C++编程

\#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <conio.h>


#define TOTAL 39               //39个关键字

#define MAXLEN 10              //关键字长度

#define HASHLEN 41             //哈希表长度


typedef struct             //哈希表 结构体  

{

char keyword[MAXLEN];     //关键字

int count;             //记录频度

int con;               //记录冲突次数

}HASH;


//全局变量

int cont=0;               //统计关键词个数

char KeyWords[TOTAL][MAXLEN]={"asm","auto","break","case","cdecl","char",

                               "const","continue","default","do","double",

   "else","enum","extern","far","float","for",

   "goto","huge","if","int","interrupt","long",

   "near","pascal","register","return","short",

   "signed","sizeof","static","struct","switch",

   "typedef","union","unsigned","void","volatile",

                               "while"};                //C语言中的39个关键字存入二维数组中

HASH HS[HASHLEN];      //建立结构体HS


//函数声明

void Show(int key);

int Read(char *filename);

int isLetter(char ch);

int isKeyWords(char *word);

int FindHX(char *keyword);

int CreatHX(char *keyword);

int GetFreePos(int key);

int GetKey(char *keyword);


void main()

{

    char orz;

    int flag=1,i,count,key,has;

char filename[128],word[MAXLEN];

    while(flag)

{

      printf("\t\tA.读取一个文件\n");

    printf("\t\tB.输出Hash表(关键字总数,冲突次数)\n");

    printf("\t\tC.查询某关键字在Hash表中的情况\n");

    printf("\t\tD.显示Hash表中的冲突关键字\n");

    printf("\t\tE.显示C语言关键字的Hash函数值(作为对照)\n");

    printf("\t\tF.退出\n\n");

printf("\t\t请输入序号(A--F):");

        scanf("%c",&orz);

switch(orz)

{

    case 'a':

case 'A':

system("cls");                         //清屏函数

               printf("请输入要读取的文件名(文件必须与程序在同一目录下):");    //比如输入:a.cpp

scanf("%s",&filename);

Read(filename);

    printf("\n按任意键返回...");

    getch();

    system("cls");

break;

    case 'b':

case 'B':

getchar();

system("cls");

printf("每次显示5行,请按回车键继续!\n");

for(i=0;i<HASHLEN;i++)

{

       Show(i);

    if((i+1)%5==0)

getchar();  //为了清晰,每次显示5行

}

    printf("关键字总数为: %d\n",cont);

    printf("\n按任意键返回...");

    getch();

    system("cls");

    break;

    case 'c':

case 'C':

system("cls");

printf("请输入你想要查找的关键字: ");

    scanf("%s",&word);

    printf("\n");

    Show(FindHX(word));

printf("\n按任意键返回...");

    getch();

    system("cls");

    break;

    case 'd':

case 'D':

system("cls");

    printf("\t冲突关键字列表\n\n");

    count=0;

    for(i=0;i<HASHLEN;i++)

{

    if(strlen(HS[i].keyword)>0)

{

    key=GetKey(HS[i].keyword);

    if(key!=i)

{

    count++;

    printf("\t关键字:%s",HS[i].keyword);

    printf("\t哈希表当前位置:%d",i);

    printf("\t冲突次数:%d\n",HS[i].con);

}

}

}

    if(count==0)

    printf("没有冲突\n");

    else

          printf("\n\t\t\t冲突关键字共:%d个\n",count);

printf("\n按任意键返回...");

    getch();

    system("cls");

    break;

    case 'e':

case 'E':

getchar();

system("cls");

printf(" C语言中的关键字和其在哈希表的位置:\n");

    for(i=0;i<TOTAL;i++)

{

has=GetKey(KeyWords[i]);

printf("[%-2d]%-11s",has,KeyWords[i]);

if((i+1)%5==0)

    printf("\n");

}

    printf("\n");

printf("\n按任意键返回...");

    getch();

    system("cls");

break;

    case 'f':

case 'F':

flag=0;

break;

default:

    system("cls");

}

}

}


int Read(char *filename)

{

char word[MAXLEN],ch;

int i;

FILE *read;                            //建立一个指像FILE类型结构体的指针变量

   if((read=fopen(filename,"r"))==NULL)   //以只读方式读取文件,如果为空执行下面的语句

{

printf("\n文件不存在,请确认好再输入!");

return -1;                     //跳出Read函数

}

while(!feof(read))          //feof()检测文件是否结束,到末尾函数值为“真”即非0

{

i=0;

ch=fgetc(read);         //读取一个字符

while(isLetter(ch)==0&&feof(read)==0)

ch=fgetc(read);     //如果不是字母就接着读取,关键字都是由字母组成的

while(isLetter(ch)==1&&feof(read)==0)

{

if(i==MAXLEN)

{

while(isLetter(ch)==1&&feof(read)==0)

{

ch=fgetc(read);       //超过MAXLEN的长度则一定不为关键字,把余下连一起的字母都读取

}

i=0;

break;

}

else

{

word[i++]=ch;             //把读取到的字母存入word数组中

ch=fgetc(read);

}

}

word[i]='\0';

if(isKeyWords(word))

{

CreatHX(word);

}

}

fclose(read);

printf("\n读取成功,文件中关键字已经存入hash表,请继续操作");

}


int isLetter(char ch) //判断是否是字母,因为关键字都是英文单词

{

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

return 1;           //是字母就返回1

else

return 0;           //不是字母就返回0

}


int FindHX(char *keyword)   //查找哈希表,分块查找

{

int key,find,tem=0;

if(!isKeyWords(keyword))    //用于查找制定关键字时判断是否为关键字

return -1;

key=GetKey(keyword);

if(strcmp(HS[key].keyword,keyword)==0)

return key;

for(find=key+1;find<HASHLEN;find++)

{                            //线性探查法顺序查找哈希表中是否已存在关键字

tem++;                   //统计冲突次数

if(strcmp(HS[find].keyword,keyword)==0)

{

HS[find].con=tem;        //若有相等的就把冲突的次数存入数组的con中

return find;

}

}

for(find=0;find<key;find++)   //后面的找不到再从前面开始找

{

tem++;

if(strcmp(HS[find].keyword,keyword)==0)

{

HS[find].con=tem;

return find;

}

}

return -1;

}


int CreatHX(char *keyword)     //建立哈希表,加个*是因为word是一个数组

{

int key;

if(!isKeyWords(keyword))   //不是关键字跳出此函数

return -1;            

key=GetKey(keyword);       //计算哈希值,根据所给哈希函数计算得出的结果

if(strlen(HS[key].keyword)>0) //判断关键字表中该位置是否存在关键字,strlen用于计算()内的字符串长度

{      //已经存在有关键字

if(strcmp(HS[key].keyword,keyword)==0)

{  //再判断哈希表中该位置的关键字是否相同

HS[key].count++;               //相同就频度加1

return 1;                      //跳出函数

}

key=FindHX(keyword);  //不相同,继续查找

if(key<0)             //没有找到相等的keyword

{

key=GetFreePos(GetKey(keyword));

if(key<0)                 //哈希表满或者计算的哈希值有问题

return -1;

strcpy(HS[key].keyword,keyword);  //将关键字插入哈希表

}

if(key<0)

return -1;

HS[key].count++;

}

else  //该位置为空,直接将关键字插入该位置中

{

strcpy(HS[key].keyword,keyword);

HS[key].count++;

}

return 1;

}


int GetFreePos(int key)  //在哈希表中给关键字找个位置插进去

{

int find,tem=0;

if(key<0||key>=HASHLEN)      

return -1;

for(find=key+1;find<HASHLEN;find++)  //先找后面的位置

{

tem++;

if(strlen(HS[find].keyword)==0)  //若这个地方为空

{

    HS[find].con=tem;            //把冲突的次数存入con中

   return find;

}

}

for(find=0;find<key;find++)          //若后面没有地方可以插入,再找前面的位置

{

tem++;

if(strlen(HS[find].keyword)==0)

{

HS[find].con=tem;

return find;

}

}

return -1; //哈希表已满

}


void Show(int key)

{

if(key<0||key>=HASHLEN)

{

printf("关键字不存在!\n");

return;

}

if(strlen(HS[key].keyword)==0)

{

printf("哈希表位置: %d  记录是空的!\n",key);

return;

}

printf("哈希表位置: %d   关键字: %-11s出现次数: %d\n",key,HS[key].keyword,HS[key].count);

cont++;

}


int GetKey(char *keyword)  //哈希函数

{  //Hash函数为:Hash(Key)=[(Key的首字母序号)*100+(Key的尾字母序号)] Mod 41

return ( keyword[0]*100+keyword[strlen(keyword)-1] ) % 41;

}


int isKeyWords(char *word)    //判断是否关键字

{

int i;

for(i=0;i<TOTAL;i++)

if(strcmp(word,KeyWords[i])==0)

return 1;

return 0;

}


站长地图