【LeetCode 28】KMP算法

public class KMP {
    
    

	int[] next;
	String pattern;
	String target; 
	
	KMP(String target, String pattern) {
    
    
		this.pattern = pattern;
		this.target = target;
		this.next = new int[this.pattern.length()];
	}
	
	public void createNext() {
    
    
		int j = 0;
		int i = 1;
		this.next[0] = 0;
		if (pattern.length() >= 2) // 至少有两个字符才能比较前缀和后缀
		{
    
    
			while (i < pattern.length()) 
			{
    
    
				// i 表示要计入的next数组的位置
				while (i < pattern.length() && pattern.charAt(i) == pattern.charAt(j))
				{
    
    
					next[i] = j+1;
					i++;
					j++;
				}
				while (j > 0 && i < pattern.length() && pattern.charAt(i) != pattern.charAt(j))
				{
    
    
					j = next[j-1];
				}
				// 一直查找到j = 0
				if (i < pattern.length() && pattern.charAt(i) != pattern.charAt(j)) 
				{
    
    
					next[i] = 0;
					i++;
				}
				// 此时j > 0
				else if (i < pattern.length() && pattern.charAt(i) == pattern.charAt(j))
				{
    
    
					next[i] = j+1;
					i++;
					j++;
				}
			}
		}
	}
	
	public void showNext() {
    
    
		for (int i = 0; i < this.next.length; i++)
			System.out.print(this.next[i]);
	}
	
	public int findStr() {
    
    
		int i = 0; // 标识主串的位置
		int j = 0; // 表示模式串的位置
		int ret = -1;
		while (true)
		{
    
    
			int rem = i - j; // j表示已经匹配的字符个数
			while (i < this.target.length() && j < this.pattern.length())
			{
    
    
				if (this.target.charAt(i) != this.pattern.charAt(j))
					break;
				i++;
				j++;
			}
			if (this.target.length() - rem < this.pattern.length()) // target剩余的字符串长度短于pattern
				break;
			if (j == this.pattern.length()) // 已经找到pattern的起始位置
			{
    
    
				ret = rem;
				break;
			}
			else if (j > 0) // 第二个字符开始出现不匹配,此时回退,回退后的新字符还是在主串的原位置进行比较
				j = this.next[j-1];
			else if (j == 0) // 第一个字符就不匹配
				i++;
		}
		return ret;
	}
	
	public static void main(String[] args) {
    
    
		KMP k = new KMP("abcaabaaab", "aabaaab");
		k.createNext();
		k.showNext();
		System.out.println();
		System.out.println(k.findStr());
	}
}

其中,next数组的构造过程参见答案提供的思路

Supongo que te gusta

Origin blog.csdn.net/juttajry/article/details/121950768
Recomendado
Clasificación