根据这周的学习任务在学习KMP算法和哈希算法,这两种算法主要都用于字符串,而且学习起来都有一定的难度,刚开始的时候一个视频要看好几遍才能弄懂,但是经过这两天的学习也有了一定的收KMP
我通过一小段简单的代码来强化我对于KMP算法的理解,next数组其实就是前缀和数组,里面存放的是当前最长相同前后缀的长度(刚开始感觉老难理解了)
//KMP算法伪代码
//j指向前缀末尾,i指向后缀末尾,j=0,i=1,依次对比
//三步(初始化、前后缀不相同、前后缀相同)
void getNext(next, s) {j = 0;next[0] = 0;//初始化for (int i = 1; i <= s.size(); i++) {while (j > 0 && s[i] != s[j]) {//不能用if,要实现多次回退j = next[j - 1];//前后缀不相同时,j要回退到前一位前缀表对应的值(循环不变量)}if (s[i] == s[j]) {j++;next[i] = j;//相等及时更新前缀表里的值}}
}
前缀和数组示例如下:
A | B | A | B | C |
0 | 0 | 1 | 2 | 0 |
下标代表的就是当前所至位置的最长相同前后缀的长度
对于hash也简单的学习了一下
哈希与字典树的关系紧密,通常将字符串转化为数值进行存放(进行取余操作),当余数相同且两个数不相同时采用链表操作,方便后续hash查询
我学习了两种hash的代码模板,一种是使用STL的map,另一种是纯hash
hash模板(map)
int n;
string s;
cin>>n;
for(int i=1;i<=n;i++){cin>>s;mp[s]++;
}
cout<<mp.size()//不同字符串的个数
hash模板(hash版)
int hash(string ss){int ans=0;int base=131;int len=ss.size();for(int i=1;i<=len;i++){ans=(ans*=base+(int)ss[i])%200005; }return ans;
}
int main(){int n;string s;for(int i=1;i<=n;i++){cin>>s;a[i]=hash(s); }int ans=1;for(int i=1;i<=n;i++){if(a[i]!=a[i+1])ans++; }cout<<ans;return 0;
}
希望之后能收获更多的东西