UVa 902 - Password Search
题目:给你一个小写字母组成大的串和一个整数n。找到里面长度为n出现最频繁的子串。
分析:字符串、hash表、字典树。
这里使用hash函数求解,仅仅做一次扫描就可以。
说明:假设频率同样输出字典序最小的。
#include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> char subs[15],buf[1000001]; char *strsub(char *str, int n) { for (int i = 0 ; i < n ; ++ i) subs[i] = str[i]; subs[n] = 0; return subs; } //hash_define typedef struct node0 { char name[15]; int count; node0*next; }hnode; hnode* hash_head[1000000]; hnode hash_node[1000000]; int hash_size; void hash_init() { hash_size = 0; memset(hash_node, 0, sizeof(hash_node)); memset(hash_head, 0, sizeof(hash_head)); } void hash_insert(char* str) { int value = 0; for (int i = 0 ; str[i] ; ++ i) value = (value*10+str[i]-'a')%1000000; for (hnode* p = hash_head[value] ; p ; p = p->next) if (!strcmp(str, p->name)) { p->count ++; return; } strcpy(hash_node[hash_size].name, str); hash_node[hash_size].count = 1; hash_node[hash_size].next = hash_head[value]; hash_head[value] = &hash_node[hash_size ++]; } void hash_max() { int max = 0; for (int i = 1 ; i < hash_size ; ++ i) if (hash_node[max].count == hash_node[i].count) { if (strcmp(hash_node[max].name, hash_node[i].name) > 0) max = i; }else if (hash_node[max].count < hash_node[i].count) max = i; printf("%s\n",hash_node[max].name); } //hash_end int main() { int n; while (~scanf("%d%s",&n,buf)) { hash_init(); int end = strlen(buf)-n; if (end < 0) continue; for (int i = 0 ; i <= end ; ++ i) hash_insert(strsub(&buf[i], n)); hash_max(); } return 0; }