全部博文(118)
分类: C/C++
2008-05-31 19:22:10
有一种简单的网页判重的方法,通过求两个网页内容的最长公共子序列(LCS)长度来判定两个网页的相似程度。如:
(网页A)老师:请用“果然”造句。
(网页B)学生:先吃水果,然后喝汽水……
它们的最长公共子序列为“果然”,长度为2。注意这里的“子序列”并不要求连续。
类似的,下面两个网页:
(网页A)老师:请用“果然”造句。
(网页B)学生:先吃水果,然后喝汽水,果然拉肚子……
最长公共子序列还是“果然”,长度为2。但不难看出,由于“果然”两个字在网页B中也曾连续出现,第二组网页比第一组更加“相似”。为了区分开这两种情况的区分度,我们改用一种称为LZW的理论。为了严格的叙述相似度的计算方法,我们首先定义“文本单元”。
假定网页用一个不包含空白字符(空格、回车换行、水平制表符)的字符串来表示。它只包含纯文本,没有标签。在计算相似度之前,你应该首先对该字符串进行处
理,划分成一个个“文本单元”。每个文本单位可以是一个中文字、英文单词(由一个或多个连续的半角英文字母和数字组成,正规表达式为[a-zA-
Z0-9]+)、或者一个标点符号。
根据上述定义,同一个标点符号的全角和半角应该被作为不同的文本单元,尽管他们看起来可能很相近;每个单独全角英文和全角数字都应该被看成一个单独的文本单元,而连续的半角英文字母和数字应被看成一个整体。总之,全角的字符可以与中文字同等对待。
这样,网页被看成文本单元序列。例如,网页“内容?123456??web2.00#”切分出的文本单元序列为(为了显示方便,用下划线分隔各文本单元):
内_容_?_1_2_345_6_?_?_web2_._00_#
而网页“why内容相似??1234567890,web#00”的切分结果为:
why_内_容_相_似_?_?_1234567890_,_web_#_00
黑体部分给出了两个网页的一个公共子序列。注意“内容”、“??”分别在两个网页中都是连续出现的文本单元。为了奖励这种情况,LZW规定一段由连续k个
文本单元组成的字符串权值为k2。在刚才的例子中,“内容”、“??”的权值均为4。但“00”是一个数字串,应当被看成一个单独的文本单元。所以权值仅
为1。
根据上述规则,公共子序列“内容 ?? 00”的权值为22+22+1=9。在所有可能的子序列中,这个权值是最大的。
给定两个网页,求他们的LZW相似度,即所有可能的公共子序列中的最大权值。
1) 输入的网页内容以GBK编码()
2) 除了大小写英文字母和数字之外的其他半角字符均视为标点符号。
包含两行,分别是网页A和B对应的字符串(不包含空白字符)。每行至少包含5个字节,最多包含200个字节。
输出仅一行,包含一个整数,为两个网页的LZW相似度。
内容?123456??web2.00#
why内容相似??1234567890,web#00
9
尽管两个网页里看上去都有“123456”但一方面第一个网页中混杂的全角和半角字符,而另一方面,即使全部改成半角字符,由于数字串“123456”和“1234567890”将分别看成一个单独的文本单元,因此无法部分匹配。