一 05
这是一个经典的求多个串的最长公共子串的问题。如果设字符串的个数为N,每个串最大的长度为L,则这道题有时间复杂度为O(N*L^4),O(N*L^3),O(N*L^2)和O(N*L)的算法。
最简单的想法是对于某一个串,取出它的所有的L^2个子串,然后再在其他每一个字符串中进行朴素的匹配,很显然是O(N*L^4)。如果生搬硬套地用KMP,那么是O(N*L^3)的算法。仔细一想,其实枚举所有的L^2个子串是完全没有必要的,仅仅取出某一个串的L个后缀,对于每一个后缀在其他的所有串中部分匹配即可,用朴素匹配就是O(N*L^3),用KMP就是O(N*L^2),可以通过所有测试点。
另外,如果用Trie,把每个串的所有后缀全部插入Trie树中,标记每个节点所属的原串。找到最深的属于所有串的节点,它的最大深度就是最长公共前缀,时间复杂度依然是O(N*L^2),但是会有一点超时。
对于这道题来说,对某个串的每个后缀进行部分模式匹配,O(N*L^2)的算法就可以了。如果想进一步探究,恐怕就要用到后缀树了,广义后缀树求最长公共子串有O(N*L)的算法,我还没有学过,现在正在苦读中。
下面是我的O(N*L^2)的KMP。
Read the rest of this entry »
标签:
2000,
KMP,
POI,
Trie,
后缀树,
子串,
字符串,
最
十 21
C++ string 详解
任何人对本文进行引用都要标明作者是Nicolai M.Josuttis
///////////////////////////////////////////////////////////////////////////////////
C++ 语言是个十分优秀的语言,但优秀并不表示完美。还是有许多人不愿意使用C或者C++,为什么?原因众多,其中之一就是C/C++的文本处理功能太麻烦,用起来很不方便。以前没有接触过其他语言时,每当别人这么说,我总是不屑一顾,认为他们根本就没有领会C++的精华,或者不太懂C++,现在我接触 perl, php, 和Shell脚本以后,开始理解了以前为什么有人说C++文本处理不方便了。
Read the rest of this entry »
标签:
C++,
string,
字符串,
技术,
用法
九 28
常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎不可能找到碰撞。
常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。对于以上几种哈希函数,我对其进行了一个小小的评测。
| Hash函数 |
数据1 |
数据2 |
数据3 |
数据4 |
数据1得分 |
数据2得分 |
数据3得分 |
数据4得分 |
平均分 |
| BKDRHash |
2 |
0 |
4774 |
481 |
96.55 |
100 |
90.95 |
82.05 |
92.64 |
| APHash |
2 |
3 |
4754 |
493 |
96.55 |
88.46 |
100 |
51.28 |
86.28 |
| DJBHash |
2 |
2 |
4975 |
474 |
96.55 |
92.31 |
0 |
100 |
83.43 |
| JSHash |
1 |
4 |
4761 |
506 |
100 |
84.62 |
96.83 |
17.95 |
81.94 |
| RSHash |
1 |
0 |
4861 |
505 |
100 |
100 |
51.58 |
20.51 |
75.96 |
| SDBMHash |
3 |
2 |
4849 |
504 |
93.1 |
92.31 |
57.01 |
23.08 |
72.41 |
| PJWHash |
30 |
26 |
4878 |
513 |
0 |
0 |
43.89 |
0 |
21.95 |
| ELFHash |
30 |
26 |
4878 |
513 |
0 |
0 |
43.89 |
0 |
21.95 |
其中数据1为100000个字母和数字组成的随机串哈希冲突个数。数据2为100000个有意义的英文句子哈希冲突个数。数据3为数据1的哈希值与1000003(大素数)求模后存储到线性表中冲突的个数。数据4为数据1的哈希值与10000019(更大素数)求模后存储到线性表中冲突的个数。
经过比较,得出以上平均得分。平均数为平方平均数。可以发现,BKDRHash无论是在实际效果还是编码实现中,效果都是最突出的。APHash也是较为优秀的算法。DJBHash,JSHash,RSHash与SDBMHash各有千秋。PJWHash与ELFHash效果最差,但得分相似,其算法本质是相似的。
在信息修竞赛中,要本着易于编码调试的原则,个人认为BKDRHash是最适合记忆和使用的。
BYVoid原创,欢迎建议、交流、批评和指正。
附:各种哈希函数的C语言程序代码
Read the rest of this entry »
标签:
C++,
哈希,
字符串,
比较
Recent Comments