赞
踩
1、题目内容:
利用Hash技术统计某个C源程序中的关键字出现的频度
2、基本要求:
扫描一个C源程序,用Hash表存储该程序中出现的关键字,并统计该程序中的关键字出现的频度。用线性探测法解决Hash冲突。设Hash函数为:
Hash(key)[(key的第一个字母序号)*100+(key的最后一个字母序号)] MOD 41
1、定义结构体
typedef struct mykey {
char data[M];//关键字
int con = 0;//冲突次数
int num = -1;//出现次数,-1表示没有
}mykey;
2、初始化
void init(); //初始化结构体数组
void create(); //建立关键词Hash表
void menu(); //显示操作菜单
//用户进入程序时自动初始化,更好的提供服务
3、读取文件(统计关键字)
void choose(int n); //选择读取的文件
void readFile(); //读取文件
void test(int n); //检测某文件
//用户能自己选择文件,选择完后进行统计,完成之后进行提示
4、打印hash表
void myprint(); //打印Hash表,输出到test.txt
打印完整hash表,存储到test.txt里面,保持数据有序,一目了然
5、查找关键字
void find();
//用户可以自行查找关键字,查看其频率和冲突次数
6、其他
bool isChar(char a);
//判断字符是否是字母
void isKey(char str[]);
//判断是否是关键字
#include<stdio.h> #include<stdlib.h> #include<string.h> #include <fstream> #define N 41 //37个关键字 char key[37][10] = { "auto","break","bool","case","char","const","continue","default", "do","double","else","enum","extern","float","false","for","goto","if","int","inline", "long","register","return","restrict","short","signed","sizeof","static","struct", "switch","typedef","true","union","unsigned","void","volatile","while" }; typedef struct mykey { char data[10]; int con ;//冲突次数 int num ;//出现次数,-1表示没有 }mykey; mykey my[N]; //hash表 int sum = 0, m,i; //总的关键字数,m用于选项 FILE* fi; //所要读取文件指针 FILE* fo; //所要写的文件指针 void init(); //初始化结构体数组 bool isChar(char a); //判断字符是否是字母 void isKey(char str[]); //判断是否是关键字 void myprint(); //打印Hash表,输出到test.txt void test(int n); //检测某文件 void choose(int n); //选择读取的文件 void readFile(); //读取文件 void find(); //查找某个关键词 void menu(); //显示操作菜单 void create(); //建立关键词Hash表 int main() { create(); menu(); return 0; } void init() {//指针为空,初始化数据 fi = NULL; sum = 0; for (int i = 0; i < N; i++) { if (my[i].num != -1) {//hash表中该位置是否有关键词 my[i].num = 0; } } } bool isChar(char a) { if (a >= 'a' && a <= 'z' || a >= 'A' && a <= 'Z') return true; else return false; } void isKey(char str[]) { int n = strlen(str); int y = (str[0] * 100 + str[n - 1]) % N; int i = 0; do { i++; if (strcmp(my[y].data, str) == 0) {//与hash表中关键词比较是否相同 if(my[y].num==-1) break; sum++;//相同关键词总数加1 my[y].num++;//出现次数加1 break; } else { y = (y + 1) % N; } } while (i <= N); } void find() { char fin[10]; bool flag = false; do { printf("请正确输入要查找的关键词:\n"); scanf("%s", fin); getchar(); for (int i = 0; i < N; i++) { if (strcmp(key[i], fin) == 0) { flag = true; break; } } } while (flag == false); int n = strlen(fin); int y = (fin[0] * 100 + fin[n - 1]) % N; bool isfind = false; int i = 0; do { i++; if (strcmp(my[y].data, fin) == 0) { isfind = true; break; } else { y = (y + 1) % N; } } while (i <= N); if (isfind == false) printf("很遗憾,该hash表内没有此关键词\n"); else printf("hash表位置:%d 关键字:%s 冲突次数:%d 出现次数:%d\n", y, my[y].data, my[y].con, my[y].num); printf("当前操作已完成\n继续查找?(y继续)\n"); if (getchar() == 'y') find(); else{ init(); menu(); } } void myprint() { printf("关键词总数:%d\n", sum); fprintf(fo, "%s %d\n", "关键词总数:", sum); char s1[13] = "hash表位置:"; char s2[7] = "无数据"; char s3[11] = "出现次数:"; char s4[11] = "冲突次数:"; char s5[9] = "关键字:"; for (int i = 0; i < N; i++) { char c[3] = " ";//用于对齐 if (i < 10) strcpy(c, " "); if (my[i].num == -1) { printf("hash表位置:%d%s无数据\n", i, c); fprintf(fo, "%s %d%s %s\n", s1, i, c, s2); } else { printf("hash表位置:%d%s关键字:%s 冲突次数:%d 出现次数:%d\n", i, c, my[i].data, my[i].con, my[i].num); fprintf(fo, "%s %d %s", s1, i, c); fprintf(fo, "%s %s ", s5, my[i].data); fprintf(fo, "%s %d ", s4, my[i].con); fprintf(fo, "%s %d\n", s3, my[i].num); } } fclose(fo);//关闭并保存文件 printf("已打印hash表\n"); printf("你可以做如下操作:\n"); printf("0.退出,1.返回菜单,2.查找某关键词\n"); do { printf("请输入正确的操作编号!\n"); scanf("%d", &m); } while (m < 0 || m>2); switch (m) { case 0: printf("感谢使用!"); exit(0); break; case 1: init(); menu(); break; case 2: find(); break; } } void readFile() { char ch; while (!feof(fi)) { //feof()函数检测文件是否结束 char word[20]; //存储一段连续字母 int i = 0; ch = fgetc(fi); //fgetc()从头取一个字符,读多少字节光标后移多少字节 while (!isChar(ch) && !feof(fi)) //取一个字母 ch = fgetc(fi); while (isChar(ch) && !feof(fi)) { //如果是字母且文件未结束,一次循环读取一段字母 if (i == 10) { while (isChar(ch) && !feof(fi)) { ch = fgetc(fi); } i = 0; break; } else { word[i++] = ch; ch = fgetc(fi); } } word[i] = '\0'; isKey(word); //检测是否为关键字 } } void menu() { system("cls"); printf("利用哈希技术统计C源程序关键字出现频度\n"); printf("你可以选择如下操作:\n"); printf("0.退出,1.测试\n"); do { printf("请输入正确的操作编号!\n"); scanf("%d", &m); } while (m != 0 && m != 1); test(m); } void test(int n) { choose(n); if (fi == NULL) { printf("no file\n"); system("pause"); menu(); } else { readFile(); printf("文件读取成功"); printf("你可以做如下操作:\n"); printf("0.退出,1.打印hash表内容,2.返回菜单,3.查找某关键词\n"); do { printf("请输入正确的操作编号!\n"); scanf("%d", &m); } while (m < 0 || m>3); switch (m) { case 0: printf("感谢使用!"); exit(0); break; case 1: myprint(); break; case 2: init(); menu(); break; case 3: find(); break; } } } void choose(int n) { switch (n) { case 0: printf("感谢使用!"); exit(0); break; case 1: char filename[20]; puts("请输入C文件名:"); scanf("%s", filename); fi=fopen(filename, "r"); fo=fopen("test.txt", "w"); break; } } void create() { for (i = 0; i < N; i++) { my[i].con=0; my[i].num=-1; } for (i = 0; i < 37; i++) { int n = strlen(key[i]); int y = (key[i][0] * 100 + key[i][n - 1]) % N; //计算关键词hash值 if (my[y].num == -1) {//若不冲突 my[y].num++; strcpy(my[y].data, key[i]); } else { //冲突 my[y].con++; //冲突加1 for(int j = 0; j < N; j++) { //寻找下一个没有存放关键词的地方 int x = ++y % N; if (my[x].num == -1) { //找到下一个没有存放关键词的地方 my[x].num++; strcpy(my[x].data, key[i]); break; } } } } }
#include<stdio.h> #include<stdlib.h> #include<string.h> #include <fstream> #define N 41 //37个关键字(蓝色字体) char key[37][10] = { "auto","break","bool","case","char","const","continue","default", "do","double","else","enum","extern","float","false","for","goto","if","int","inline", "long","register","return","restrict","short","signed","sizeof","static","struct", "switch","typedef","true","union","unsigned","void","volatile","while" }; typedef struct mykey { char data[10]; int con = 0;//冲突次数 int num = -1;//出现次数,-1表示没有 }mykey; mykey my[N]; //hash表 int sum = 0, m; //总的关键字数,m用于选项 FILE* fi; //所要读取文件指针 FILE* fo; //所要写的文件指针 void init(); //初始化结构体数组 bool isChar(char a); //判断字符是否是字母 void isKey(char str[]); //判断是否是关键字 void myprint(); //打印Hash表,输出到test.txt void test(int n); //检测某文件 void choose(int n); //选择读取的文件 void readFile(); //读取文件 void find(); //查找某个关键词 void menu(); //显示操作菜单 void create(); //建立关键词Hash表 int main() { system("color f0"); create(); menu(); return 0; } void init() {//指针为空,初始化数据 fi = NULL; sum = 0; for (int i = 0; i < N; i++) { if (my[i].num != -1) {//hash表中该位置是否有关键词 my[i].num = 0; } } } bool isChar(char a) { if (a >= 'a' && a <= 'z' || a >= 'A' && a <= 'Z') return true; else return false; } void isKey(char str[]) { int n = strlen(str); int y = (str[0] * 100 + str[n - 1]) % N; int i = 0; do { i++; if (strcmp(my[y].data, str) == 0) {//与hash表中关键词比较是否相同 sum++;//相同关键词总数加1 my[y].num++;//出现次数加1 break; } else { y = (y + 1) % N; } } while (i <= N); } void find() { char fin[10]; bool flag = false; do { printf("请正确输入要查找的关键词:\n"); scanf_s("%s", fin, 10); getchar(); for (int i = 0; i < N; i++) { if (strcmp(key[i], fin) == 0) { flag = true; break; } } } while (flag == false); int n = strlen(fin); int y = (fin[0] * 100 + fin[n - 1]) % N; bool isfind = false; int i = 0; do { i++; if (strcmp(my[y].data, fin) == 0) { isfind = true; break; } else { y = (y + 1) % N; } } while (i <= N); if (isfind == false) printf("很遗憾,该hash表内没有此关键词\n"); else printf("hash表位置:%d 关键字:%s 冲突次数:%d 出现次数:%d\n", y, my[y].data, my[y].con, my[y].num); printf("当前操作已完成\n继续查找?(y继续)\n"); if (getchar() == 'y') find(); else { init(); menu(); } } void myprint() { printf("关键词总数:%d\n", sum); fprintf(fo, "%s %d\n", "关键词总数:", sum); char s1[13] = "hash表位置:"; char s2[7] = "无数据"; char s3[11] = "出现次数:"; char s4[11] = "冲突次数:"; char s5[9] = "关键字:"; for (int i = 0; i < N; i++) { char c[3] = " ";//用于对齐 if (i < 10) strcpy_s(c, " "); if (my[i].num == -1) { printf("hash表位置:%d%s无数据\n", i, c); fprintf(fo, "%s %d%s %s\n", s1, i, c, s2); } else { printf("hash表位置:%d%s关键字:%s 冲突次数:%d 出现次数:%d\n", i, c, my[i].data, my[i].con, my[i].num); fprintf(fo, "%s %d %s", s1, i, c); fprintf(fo, "%s %s ", s5, my[i].data); fprintf(fo, "%s %d ", s4, my[i].con); fprintf(fo, "%s %d\n", s3, my[i].num); } } fclose(fo);//关闭并保存文件 printf("已打印hash表\n"); printf("你可以做如下操作:\n"); printf("0.退出,1.返回菜单,2.查找某关键词\n"); do { printf("请输入正确的操作编号!\n"); scanf_s("%d", &m); } while (m < 0 || m>2); switch (m) { case 0: printf("感谢使用!"); exit(0); break; case 1: init(); menu(); break; case 2: find(); break; } } void readFile() { char ch; while (!feof(fi)) { //feof()函数检测文件是否结束 char word[20]; //存储一段连续字母 int i = 0; ch = fgetc(fi); //fgetc()从头取一个字符,读多少字节光标后移多少字节 while (!isChar(ch) && !feof(fi)) //取一个字母 ch = fgetc(fi); while (isChar(ch) && !feof(fi)) { //如果是字母且文件未结束,一次循环读取一段字母 if (i == 10) { while (isChar(ch) && !feof(fi)) { ch = fgetc(fi); } i = 0; break; } else { word[i++] = ch; ch = fgetc(fi); } } word[i] = '\0'; isKey(word); //检测是否为关键字 } } void menu() { system("cls"); init(); printf("利用哈希技术统计C源程序关键字出现频度\n"); printf("你可以选择如下操作:\n"); printf("0.退出,1.测试\n"); do { printf("请输入正确的操作编号!\n"); scanf_s("%d", &m); } while (m != 0 && m != 1); test(m); } void test(int n) { choose(n); if (fi == NULL) { printf("no file\n"); system("pause"); menu(); } else { readFile(); printf("文件读取成功"); printf("你可以做如下操作:\n"); printf("0.退出,1.打印hash表内容,2.返回菜单,3.查找某关键词\n"); do { printf("请输入正确的操作编号!\n"); scanf_s("%d", &m); } while (m < 0 || m>3); switch (m) { case 0: printf("感谢使用!"); exit(0); break; case 1: myprint(); break; case 2: init(); menu(); break; case 3: find(); break; } } } void choose(int n) { switch (n) { case 0: printf("感谢使用!"); exit(0); break; case 1: char filename[20]; puts("请输入C文件名:"); scanf_s("%s", filename, 20); fopen_s(&fi, filename, "r"); fopen_s(&fo, "test.txt", "w"); break; } } void create() { for (int i = 0; i < 37; i++) { int n = strlen(key[i]); int y = (key[i][0] * 100 + key[i][n - 1]) % N; //计算关键词hash值 if (my[y].num == -1) {//若不冲突 my[y].num++; strcpy_s(my[y].data, key[i]); } else { //冲突 my[y].con++; //冲突加1 int count = -1, x; while (count++ < N) { //寻找下一个没有存放关键词的地方 x = ++y % N; if (my[x].num == -1) { //找到下一个没有存放关键词的地方 my[x].num++; strcpy_s(my[x].data, key[i]); break; } } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。