一个字符串问题的思考

本文探讨了一种字符串问题,即如何求解文本中以字符A开头,B结尾的子串数量。文章通过分析和设计,提出了三种算法:蛮力法、分治法和动态规划法,详细解释了每种方法的思路和实现,并通过实例展示了算法的应用。最后指出,预处理字符串的KMP算法也可用于此类问题,提供了一种O(n)时间复杂度的解决方案。
摘要由CSDN通过智能技术生成



一、 问题描述:

        求解给定文本text 中以字符 A 开头, 字符B 结尾的子串数量。例如,文本ABCAAB 中以A开头B结尾的子串分别为AB, ABCAAB, AAB, AB 共4个。

二、 问题分析及算法设计:

  字符串问题求解的通用策略: 我从《TCPL》中学到的印象最深的一点,就是“逐字符处理”策略(同时注意 '\0'的处理)。

首先,使用蛮力法求解: 设置两个下标 i , j ; i 指向已搜索到的 A 的位置, j 指向已搜索到的B的位置。 算法描述如下:

STEP1:初始化 i = 0 , j = 0.  从字符串最左边开始。

STEP2:    用下标 i 遍历搜索A,若搜索到A,则记下 i 的位置并转至STEP2; 若到达字符串末尾仍没有搜索到,则转至 STEP4;
STEP3: 初始化 j 为 i 的下一个位置并开始搜索B: 若到达字符串末尾没有搜索到,则 i 移到下一个位置并转至STEP1;若搜索到B,则子串数目次数加一,并继续向前搜索,直到字符串末尾并转至STEP1;
STEP4: 搜索结束,退出算法。

例子: ABCAAB

       第一趟: A: i = 0, B: j = 1, 5   num = 2; 

       第二趟: A: i = 3, B: j = 5       num = 1;

       第三趟: A: i = 4, B: j = 5       num = 1

        共计: 2 + 1 + 1 = 4.

        这样的蛮力算法,其时间效率取决于A在字符串中出现的次数Na, T(n) = O(n * Na), n 是字符串长度。 也可以从右往左搜索, 其时间效率为 T(n) = O(n * Nb), Nb是 B 在字符串中出现的次数。 如果知道A和B在文本中出现的次数,那么就可以选择从左往右或者从右往左的遍历方式。最差情况下,例如全A串,则效率为O(n*n). 

        有没有可能找到更好的算法呢? 

        我们知道,分治算法通常能达到 O(nlogn)的效率,只要合并部分的时间能达到O(n) 。 那么,这个问题是否可以采用分治法来求解呢? 答案是肯定的。

        假设 N[left: right] 是文本 text[left:right] 中以A开始B结尾的子串数量, 则整个文本中以A开始B结尾的子串数量为 N[0:n] = N[0:n/2] + N[n/2+1: n] + Na * Nb. Na 是 A 在 text[0:n/2]中出现的次数, Nb 是 B 在 text[n/2+1: n] 中出现的次数; 因为在后半段文本中的所有B都出现在前半段文本中的所有A之后(每个A与每个B都形成合乎要求的子串),而在后半段文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值