`

<算法书>最长前缀是逆串的子串

阅读更多

问题描述 :设T是长为n的文本串。描述一个找出T的最长前缀的O(n)时间的方法,该前缀也是T的逆串的一个子串。 (来自《Algorithm Design》(中文版:算法分析与设计) - Chapter9 - 文本处理 - 创新题C-9.12)

 

分析:既然要在O(n)时间内完成,KMP算法是可以考虑的。根据题目要求我们发现要让T的前缀匹配到T的逆串。那么我们可以把T的逆串作为主串,T作为模式串。对KMP算法做如下修改:

 

(1) 在匹配逻辑中,主串指针 i 从T逆向开始查找,即i=(T.length-1) ——> 0。模式串指针 j 从T正向开始查找,即j=0 ——> (T.length-1)。这样就不用首先做T逆向的处理了。

 

(2) 每一次T[i]==T[j](i 为T的逆序指针,j为T的顺序指针),都用一个字符串累加起来。直到遇上不相等的时候,则保留原字符串,清空后重新开始累加。直到 i=0为止。此时,所有保留的字符串都是满足条件的T的前缀子串,在比较长度取出最大的字符串即可。

 

Java代码如下:

public class SelfKMP {

	private int[] next=null;
	private char[] mainAry=null;
        //记录匹配上的所有前缀
	ArrayList<String> path=new ArrayList<String>();	
	
	
	public KMP(String main){		

		this.mainAry=new char[main.length()+1];
                System.arraycopy(main.toCharArray(),0,mainAry,1,main.length());
		this.next=new int[main.length()+1];
	}
	/**
	 * KMP匹配
	 * @param pos 从主串起始位置开始
	 */
	public String maxMatch(){

		failFunction();
		
		int i=mainAry.length-1;
		int j=1;
		String temp="";
		while(i>0&&j<mainAry.length){
			
			if(j==0||mainAry[i]==mainAry[j]){
				if(j!=0)
					temp=temp+mainAry[j]; //记录每一次想等的字符
				--i;
				++j;
			}else{
				array.add(temp); 
				temp="";
				j=next[j];
			}
		}
		
                String maxPreStr="";
                for(String s:array){
                      if(s.length>maxPreStr.length){
                              maxPreStr=s;
                      }
                }

                return maxPreStr;
		
	}
	/**
	 * 匹配串失效函数
	 */
	private void failFunction(){
		
		int i=1,j=0;
		next[1]=0;
		while(i<mainAry.length-1){
			if(j==0||mainAry[i]==mainAry[j]){
				next[++i]=++j;
			}else{
				j=next[j];
			}
		}
	}
	
	/**
	 * 测试
	 * @param args
	 */
	public static void main(String[] args) {
		
		SelfKMP kmp=new SelfKMP("acabaabaabcacaabc");
		System.out.println(kmp.maxMatch());
	}

}

      效率: 这个算法和KMP没有什么不同,因此n长度的T串最先需要付出O(n)代价来计算T的失效函数。然后需要O(n)来匹配前缀,最后付出O(x)代价来找最大字符串,其中x<n为所有满足条件的T前缀串的数量。

 

0
0
分享到:
评论

相关推荐

    罗穗骞《后缀数组——处理字符串的有力工具》(有算法源码和解题源码)

    通过计算LCP(Longest Common Prefix,最长公共前缀)数组,可以找出两个或多个字符串的最长公共子串。LCP数组是基于后缀数组的,表示相邻两个后缀的最长公共前缀的长度。源码实现这部分功能有助于读者更好地掌握...

    后缀数组相关题解1

    后缀数组的构建和应用通常涉及到字符串的最长公共前后缀、最长重复子串、最长回文子串等问题。 首先,我们来看【POJ 1743】这个问题,它要求找出一个乐曲序列中满足特定条件的最长重复主题。这里的条件包括主题长度...

    algorithm on strings

    9. **后缀数组和后缀树**:这两种数据结构是处理字符串问题的强大工具,常用于最长公共前缀、最长重复子串等问题,也可用于高效的字符串匹配。 10. **Manacher's Algorithm**:针对奇偶回文子串的高效查找,...

    kmp算法模式匹配的实现-C语言.zip

    KMP(Knuth-Morris-Pratt)算法是一种在文本串(text)中查找子串(pattern)的著名字符串搜索算法,由Donald Knuth、 Vaughan Pratt和James Morris三人提出。这个算法避免了对已匹配部分的重复比较,提高了效率。在...

    《字串理论》

    4. **滑动窗口**:在处理长字符串时,滑动窗口技术允许我们在固定大小的窗口内检查子串,这在计算最频繁出现的子串或寻找最长公共子串等问题中很有用。 5. **编辑距离**:也称为Levenshtein距离,它衡量两个字符串...

    SwordOffer代码

    5. **字符串处理**:包括字符串匹配(如KMP算法)、最长公共前缀、最长回文子串等,这些在文本处理和信息检索等领域至关重要。 6. **图论算法**:如最小生成树(Prim或Kruskal算法)、最短路径(Dijkstra或Floyd...

    04 KMP.rar

    这一步可以通过动态规划实现,对于模式串中的每个位置i,计算最长的前缀和后缀相同的部分,长度记为`pi`。 2. 然后,从文本串的第一个字符开始,逐个字符与模式串进行比较。如果匹配成功,则移动模式串的下一个字符...

    算法学习代码库

    8. **字符串处理**:KMP算法、Rabin-Karp算法等用于模式匹配,Z算法和Manacher's算法用于找出字符串中的最长回文子串。 9. **编码技巧**:如位运算、前缀和、 Fenwick树(也称作二分查找树)和Segment Tree等,这些...

    算法面试题100道for阿里、百度、腾讯、京东、美团、今日头条.pdf

    - **特定算法题目的解决**:如判断字符串的旋转,求最长无重复字符子串等。 这本书通过详尽的算法题目和知识点,提供了一个完整的面试准备方案,不仅涉及了传统的数据结构和算法,还包括了一些高级数据结构与算法,...

    关于后缀树的超牛B论文,有详细的图解

    - **最长公共前缀**:在后缀树中,从根节点到任何内部节点的路径代表了一个共享前缀,最长的路径即为最长公共前缀。 - **模式计数**:计算一个模式在字符串中出现的次数。 - **基因序列比对**:在生物信息学中,后缀...

    数据结构与算法分析+C+++描述代码

    9. **字符串处理**:KMP算法、Boyer-Moore算法、Rabin-Karp算法等用于字符串匹配,Z-算法、Manacher's算法用于求解最长回文子串。 10. **图论算法**:如Floyd-Warshall算法求解所有顶点间的最短路径,Dijkstra算法...

    Data structures and algorithms in C++,(CODE)

    算法部分,书中可能会涵盖排序(如冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等)、搜索(如线性搜索、二分搜索、深度优先搜索、广度优先搜索)、字符串处理(如最长公共子串、KMP算法)、图算法...

    acm-book.pdf

    最长回文子串问题是找出给定字符串中最长的回文子串。可以通过动态规划等方法解决。 ### 七、数论 #### 7.1 中国剩余定理 中国剩余定理是一种用于解决同余方程组的理论,可以有效地求解多个同余方程的解。 #### ...

    C 常用算法程序集-徐士良

    - **动态规划求解最长公共子序列**:找到两个字符串的最长不重复子串。 - **Trie树**:一种特殊的树结构,用于高效地存储和检索前缀相同的字符串。 5. **数据结构**: - **栈**:后进先出(LIFO)的数据结构,常...

    算法解析ACM

    字符串是一种特殊的线性数据结构,广泛应用于文本处理等领域。 **案例分析:Pku1961—Period** 题目描述:给定一个字符串,需要找出它的最小重复周期。此问题可以通过字符串匹配算法来解决,如KMP算法等。 **案例...

    coding-interview-in-java.pdf

    - 找出字符串数组中所有字符串的最长公共前缀。这是一个字符串处理的基础问题。 32. NextPermutation - 实现获取下一个排列的函数。这涉及到对排列的生成和排序算法的理解。 33. SearchInsertPosition - 给定一...

    编程珠玑习题集锦

    - height数组记录相邻后缀的最长公共前缀,有助于计算最长公共子串。 - 倍增算法和DC3算法可用于构建后缀数组,它们在时间和空间上都是线性的。 8. **统计字符串出现次数** - 利用C++中的`map`容器,可以高效地...

    去年我去海尔面试的题目

    - 实现KMP算法的关键是构建next数组或nextval数组,用以存储前缀和后缀相等的最长子串长度,从而指导后续的匹配过程。 综上所述,这些面试题目涵盖了从基本的人际交往能力到专业技能的多个层面,旨在全面评估应聘者...

Global site tag (gtag.js) - Google Analytics