89.hash算法实现CSDN密码处理
- 初始化,数据的行数,hash链表结构体,存储头结点
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <stdlib.h> 4 char path[256] = "csdn.txt"; 5 //数据的行数 6 #define N 6428633 7 //字符串hash算法 8 unsigned int BKDRHash(char *str); 9 10 //hash链表结构体(结构体) 11 struct beitai 12 { 13 char *pstr;//存储字符串 14 struct beitai *pNext;//下一个节点 15 }; 16 17 //头结点 18 struct info 19 { 20 struct beitai *pbt; 21 }; 22 23 //保持所有头结点 24 struct info *pall = NULL;
- 字符串hash算法
1 //hasn算法 2 unsigned int BKDRHash(char *str) 3 { 4 //和数据对应的位数有关 5 unsigned int seed = 13131313; // 31 131 1313 13131 131313 etc.. 6 unsigned int hash = 0; 7 8 while (*str) 9 { 10 hash = hash * seed + (*str++); 11 } 12 13 return (hash & 0x7FFFFFFF); 14 }
- 实现读取一行的数据的修改,并对这个字符串进行hash算法
1 void changestr(char *str) 2 { 3 //备份地址 4 char *pbak = str; 5 //去除空格 6 //下标 7 int i = 0; 8 //游标 9 int j = 0; 10 while ((str[i] = str[j++]) != '\0') 11 { 12 if (str[i] != ' ') 13 { 14 i++; 15 } 16 } 17 //截断 18 char *p1 = strstr(pbak, "#"); 19 if (p1 != NULL) 20 { 21 *p1 = '\0'; 22 } 23 }
- 载入内存
1 void init() 2 { 3 4 pall = malloc(N*sizeof(struct info)); 5 memset(pall, 0, N*sizeof(struct info));//清空 6 7 //打开文件 8 FILE *pf = fopen(path, "r"); 9 for (int i = 0; i < N; i++) 10 { 11 char str[100] = { 0 }; 12 char strbak[100] = { 0 }; 13 //读取一行 14 fgets(str, 100, pf); 15 //拷贝 16 strcpy(strbak, str); 17 //字符串处理 18 changestr(str); 19 //获取hash对应的数字 20 unsigned int data = BKDRHash(str); 21 //进行取余 22 unsigned int id = data %N; 23 pall[id].pbt = addstr(pall[id].pbt, strbak);//找到链表节点,插入 24 } 25 fclose(pf); 26 }
- 插入节点
1 //插入 2 struct beitai *addstr(struct beitai *phead, char *str) 3 { 4 //开辟节点 5 struct beitai *pnew = calloc(1, sizeof(struct beitai)); 6 //获取字符串长度并开辟内存 7 int length = strlen(str); 8 pnew->pstr = calloc(length + 1, sizeof(char)); 9 //拷贝 10 strcpy(pnew->pstr, str); 11 //下一个结点为NULL 12 pnew->pNext = NULL; 13 //如果头结点为空 14 if (phead==NULL) 15 { 16 phead = pnew; 17 } 18 //否则头部插入 19 else 20 { 21 pnew->pNext = phead; 22 phead = pnew; 23 24 } 25 return phead; 26 }
- 实现查询
1 //实现查询 2 void find(struct beitai *phead, char *findstr) 3 { 4 while (phead!=NULL) 5 { 6 char*ps = strstr(phead->pstr, findstr); 7 if (ps!=NULL) 8 { 9 printf("%s", phead->pstr);//查找 10 } 11 phead = phead->pNext; 12 } 13 }
- 获取有多少行
1 int getN() 2 { 3 FILE *pf = fopen(path, "r"); 4 if (pf == NULL) 5 { 6 return -1; 7 } 8 else 9 { 10 int i = 0; 11 while (!feof(pf)) 12 { 13 char str[100] = { 0 }; 14 fgets(str, 100, pf);//读取 15 i++; 16 } 17 fclose(pf); 18 return i; 19 } 20 }
- 主函数
1 //主函数 2 void main() 3 { 4 //初始化并载入内存 5 init(); 6 //查询 7 while (1) 8 { 9 char str[100] = { 0 }; 10 scanf("%s", str); 11 unsigned int id = BKDRHash(str) % N; 12 find(pall[id].pbt, str); 13 } 14 system("pause"); 15 }