Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
分析:题目要求返回needle字符串在haystack中第一次出现的位置,没有出现的话就返回-1。
首先取出needle首个字符在haystack中的位置。
然后截取haystack使其获得与needle首字符相同的字符串。
接着判断haystack是否以needle开头,若是则返回保存的待返回的下标。
若不是,去除haystack的第一个字符,继续循环上面的步骤,直到找到正确下标或找不到返回-1.
/** * 判断needle字符串在haystack中第一次出现的位置,没有出现的话就返回-1。 * 首先取出needle首个字符在haystack中的位置。 * 截取haystack使其获得与needle首字符相同的字符串。 * 判断haystack是否以needle开头,若是则返回保存的待返回的下标。 * 若不是,去除haystack的第一个字符,继续循环上面的步骤,直到找到正确下标或找不到返回-1. * */ public int strStr(String haystack, String needle) { int resultIndex = 0;//保存的是最后返回的值 int hlen = haystack.length(); int nlen = needle.length(); if(nlen<=0){ return 0; } /* 首先取出needle首个字符在haystack中的位置 */ char firstC = needle.charAt(0); while (nlen <= hlen) { int start = haystack.indexOf(firstC);// 找到needle首个字符在haystack的位置。 if(start == -1){//start==-1表示剩下的字符串中找不到needle return -1; } resultIndex = resultIndex+start+1; haystack = haystack.substring(start);// 截取haystack获得与needle首字符相同的字符串 if (haystack.startsWith(needle)) {/* 如果找到则返回start */ return resultIndex-1; }else {/* 否则先把haystack的首字符去掉,然后再后面计算是否满足条件 */ if(haystack.length()>=1){ haystack = haystack.substring(1); }else{ return -1; } } hlen = haystack.length();//这个地方之前没有加,现在加上之后效率提高好多,因为加上之后就可以直接在nlen<hlen的时候返回-1. nlen = needle.length(); } return -1; }
方法二:字符串匹配可以采用修改后的KMP算法来实现。
Step1:获取模式串needle的next函数值,next[j]的值表示在needle[j]匹配失败的时候needle需要回溯到的下标。
Step2:遍历字符串haystack,当haystack[i]与needle[j]失败时j需要退回到next[j]指示的下标。直到haystack中的字符被遍历完。
/** * 判断needle字符串在haystack中第一次出现的位置,没有出现的话就返回-1。 * 用改进的kmp算法实现. * Step1:获取模式串needle的next函数值,next[j]的值表示在needle[j]匹配失败的时候needle需要回溯到的下标。 * Step2:遍历字符串haystack,当haystack[i]与needle[j]失败时j需要退回到next[j]指示的下标。直到haystack中的字符被遍历完。 * */ public int strStr(String haystack, String needle) { int hlen = haystack.length(); int nlen = needle.length(); if(nlen == 0){ return 0; } if(hlen == 0){ return -1; } int i=0; int j=0; int[] next = new int[nlen]; /*Step1:获取模式串needle的next函数值*/ getNext(needle,next); /*Step2:遍历字符串haystack,当haystack[i]与needle[j]失败时j需要退回到next[j]指示的下标。直到haystack中的字符被遍历完。*/ while(i<hlen && j<nlen){ if(j==-1 || haystack.charAt(i) == needle.charAt(j)){ i++; j++; }else{ j = next[j]; } } /*整理返回结果*/ if(j == nlen){ return i-nlen; }else{ return -1; } } /** * 计算模式串needle的next数组。 */ public void getNext(String needle,int next[]){ int len = needle.length(); next[0] = -1; int j = -1; /*依次遍历字符串needle,计算每个字符匹配失败时应该返回的next[i]的值*/ int i=0; while(i<len-1){ /*如果下标i和下标j对应的字符相等,或者j=-1,则i和j都向后移动一个*/ if(j == -1 || needle.charAt(i)== needle.charAt(j)){ j++; i++; if(needle.charAt(i) != needle.charAt(j)){ System.out.println("j = "+j); next[i] = j; }else{ next[i] = next[j]; } }else{ j = next[j]; } } }