字符串系数-Python2.7-2018腾讯秋招

8 篇文章 0 订阅
6 篇文章 0 订阅
  • 题目描述:
    对于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%,所以这个思路应该不是解决这个问题的最好办法,欢迎交流讨论。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值