题目描述:
对于A和B两个字符串的字符串系数按照如下规则定义:
1.对于每一个A的长度为k的不同子串,我们统计在B中的出现的次数。
2.A和B的字符串系数就是所有出现次数之和。
例如:A = “abab”,B = “ababab”,k = 2
A有两个长度为2的不同的子串”ab”和”ba”,在B中”ab”出现了3次,”ba”出现了2次,所以A和B的字符串系数为3+2=5。
现在给出两个字符串A、B和整数k,请你计算A和B的字符串系数。输入描述:
输入包括三行。
第一行包括一正整数k(1<=k<=|A|)。
第二行一个字符串A(1<=|A|<=100000)。
第三行一个字符串B(1<=|B|<=100000)。
其中|A|表示字符串A的长度。输出描述:
输出一个整数,表示A和B的字符串系数。输入示例:
输入:
2
abab
ababab
输出:
5思路:
前两天刚写了一篇关于利用KMP算法匹配字符串的博客KMP-字符串匹配算法 Python 2.7实现,所以就直接拿来用了。所以思路就是将字符串A进行划分为多个子串,每个子串的长度为k。子串出现的次数用一个字典存储,保证不会重复计算。每个子串都进行一次KMP。最后,通过率为70%。
Python2.7实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/9/16 16:34
# @Author : Qiankun Wang
# @File : Tencent1.py
class KMP:
# build prefix table using shorter strings firstly
def prefix_table(self,pattern,n):
len = 0
i = 1
while i < n:
# print len,i
if pattern[i] == pattern[len]:
len += 1
prefix[i] = len
i += 1
else:
if len > 0:
len = prefix[len - 1]
else:
prefix[i] = len
i += 1
return prefix
# move the prefix table one step backward
def move_prefix_table(self,pattern,n):
for i in range(n-1,0,-1):
prefix[i] = prefix[i-1]
prefix[0] = -1
return prefix
# judge whether pattern is in text using method of kmp search
def kmp_search(self,pattern,text):
i = 0 # corresponding to the index of text(longer strings)
j = 0 # corresponding to the index of pattern(shorter strings)
flag = 0
res = 0
while i < m:
if j == n - 1 and text[i] == pattern[j]:
flag = 1
# print "Find pattern at index %d of text"%(i-j) # print index at which pattern lies in text
res += 1
j = prefix[j]
if text[i] == pattern[j]:
i += 1
j += 1
else:
j = prefix[j]
# reach at the starting point,move both index i and j one step backward
if j == -1:
i += 1
j += 1
# if flag == 0:
# print "pattern is not in text"
return res
if __name__ == "__main__":
# pattern = 'ABABCABAA'
# text = 'ABABABCABAABABABAB'
k = int(raw_input())
a = raw_input().strip("'")
text = raw_input().strip("'")
# pattern = 'abab'
# text = 'ababab'
m = len(text)
ans = 0
freq = {}
# 初始化每个子串出现的次数,初始值都为0。
for i in range(len(a)- k+1):
pattern = a[i:i + k]
freq[pattern] = 0
# 对字符串A进行划分,每次都调用一次KMP
for i in range(len(a) - k+1):
pattern = a[i:i + k]
if freq[pattern] == 0:
n = len(pattern)
prefix = [0] * n
s = KMP()
s.prefix_table(pattern,n)
s.move_prefix_table(pattern,n)
temp = s.kmp_search(pattern,text)
#计算过的子串,其出现次数设为1
freq[pattern] += 1
# 将每个子串出现的次数求和。
ans += temp
print ans
- 写在后面:
这个代码只是直接在原代码上做了一些修改。由于最后通过率只有70%,所以这个思路应该不是解决这个问题的最好办法,欢迎交流讨论。