给你一个文本串 T ,一个非空模板串 S ,问 S 在 T 中出现了多少次
数据范围:
要求:空间复杂度 ,时间复杂度
// 超时算法 public int kmp (String S, String T) { // write code here int ls=S.length() ,lt=T.length() ,res=0; for(int i=0;i+ls<=lt;i++){ if(S.equals(T.substring(i,i+ls))){ res++; } } return res; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算模板串S在文本串T中出现了多少次 * @param S string字符串 模板串 * @param T string字符串 文本串 * @return int整型 */ public int kmp (String S, String T) { if (S.length() == 0 || S.length() > T.length()) return 0; int[] next = getNext(S); int j = 0, count = 0; for (int i = 0; i < T.length(); i++) { while (j > 0 && S.charAt(j) != T.charAt(i)){ j = next[j - 1]; } if (S.charAt(j) == T.charAt(i)){ j++; } if (j == next.length){ count++; //匹配成功后,计数,按照当前未匹配成功,回退next[] j = next[j - 1]; } } return count; } public int[] getNext(String s){ int[] next = new int[s.length()]; int j = 0; next[0] = j; for (int i = 1; i < s.length(); i++) { while (j > 0 && s.charAt(j) != s.charAt(i)){ j = next[j - 1]; } if (s.charAt(i) == s.charAt(j)){ j++; } next[i] = j; } return next; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算模板串S在文本串T中出现了多少次 * @param S string字符串 模板串 * @param T string字符串 文本串 * @return int整型 */ public int kmp (String S, String T) { // write code here int ans = 0; char[] sBuf = S.toCharArray(); char[] tBuf = T.toCharArray(); int[] next = new int[S.length()]; getNext(sBuf, next); int i = 0, j = 0; while (i < tBuf.length) { if (tBuf[i] == sBuf[j]) { i++; j++; } else if (j > 0) { j = next[j - 1]; } else { i++; } if (j == sBuf.length) { ans++; j = next[j - 1]; } } return ans; } void getNext(char[] buf, int[] next) { int j = 0, i = 1; next[0] = 0; // char[] buf = S.toCharArray(); while (i < buf.length) { if (buf[i] == buf[j]) { next[i++] = ++j; } else { if (j > 0) { j = next[j - 1]; } else { next[i++] = 0; } } } } }
public class Solution { public int kmp (String S, String T) { int res = 0; int[] next = new int[S.length()]; getNext(next, S); int j = 0; int i = 0; while (i < T.length()) { // 退到头或相等,i指针往后 if (j == 0 || T.charAt(i) == S.charAt(j)){ i++; j++; } else { // j回退,防止溢出 if (j == 0) j = 0; else j = next[j - 1]; } if (j == S.length()){ // 找到一个子串,j回退 res++; j = next[j - 1]; } } return res; } void getNext(int next[], String S){ int j = 0; next[0] = 0; // 初始化 for (int i = 1; i < S.length(); i++) { // 前缀不相同时;注意此处回退循环,退到相等 while (j > 0 && S.charAt(i) != S.charAt(j)) j = next[j - 1]; // 前缀相同时,更新前缀指针和next数组 if (S.charAt(i) == S.charAt(j)) { j++; next[i] = j; } } } }人家三个学者提出来的算法,没提前学过或专门学过,基本没人能直接写出来。完整学过理解之后才能模仿实现,这种题也能算中等题?。。
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算模板串S在文本串T中出现了多少次 * @param S string字符串 模板串 * @param T string字符串 文本串 * @return int整型 */ public int kmp (String S, String T) { char[] t = T.toCharArray(), p = S.toCharArray(); int i1 = 0, i2 = 0, res = 0; int[] next = next(p); while(i1 < t.length && i2 < p.length){ if(t[i1] == p[i2]){ i1 ++; i2 ++; }else if(next[i2] == -1){ i1 ++; }else { i2 = next[i2]; } if(i2 == p.length){ res ++; i2 = next[i2-1]; i1 --; } } if(i2 == p.length){ } return res; } int[] next(char[] p){ if(p.length == 1){ return new int[]{-1}; } int[] next = new int[p.length]; next[0] = -1; next[1] = 0; //cn 表示next[i-1] int i = 2, cn = 0; while(i < p.length){ if(p[i - 1] == p[cn] ){ next[i ++] = ++cn; }else if(cn > 0){ cn = next[cn]; }else { next[i++] = 0; } } return next; } }
public class Solution { public int kmp (String S, String T) { // write code here int result=0; for(int i=0;i<T.length();i++) { int ff=i+S.length(); if(ff<=T.length()) { String fsString= T.substring(i, ff); if(S.equals(fsString)) { result++; } } } return result; } }