字符串是面试中常见的问题。今天看到这个问题,仔细考虑了下,只想到了最原始方法,找到字符串的所有字串,然后遍历。复杂度太高了。
上网查了一些资料,明白了算法。下面简单介绍下,然后给出java代码。
首先要搞清子串的概念,1个字符也是子串,此问题是求出连续出现次数最多的子串。如果字符串是abcbcbcbc,这个连续出现次数最多的子串是bc,连续出现的次数是3。
如果类似的是abcccabc,则结果是c。次数也是3。
算法描述:
首先穷举出所有后缀子串,如果一个字符串str = abcbcbcbc
则所有的后缀子串是
substrs[0] = abcbcbcbc
substrs[1] = bcbcbcbc
substrs[2] = cbcbcbc
substrs[3] = bcbcbc
substrs[4] = cbcbc
substrs[5] = bcbc
substrs[6] = cbc
substrs[7] = bc
substrs[8] =c
遍历这些后缀子串,依次进行比较:(按字符串个数依次比较)
如果substrs[1]的第一个字符 和substrs[0]的第一个相等,则比较substrs[2]的第一个和substrs[0]的第一个。
如果substrs[1]的前两个字符 和substrs[0]的前两个相等,则比较substrs[2]的前两个和substrs[0]的前两个。
依次进行,可得到结果。
java代码:
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
public class TestSubString {
public static Map<Integer,String> fun(String str){
Map<Integer,String> map = new HashMap<Integer,String>();
Vector<String> substrs = new Vector<String>();
int maxCount = 1,count =1;
String substr = null;
int i,len = str.length();
for(i=0;i<len;i++){
substrs.add(i, str.substring(i, len));
}
System.out.println(substrs.toString());
for(i=0;i<len;i++){
for(int j=i+1;j<len;j++){
count = 1;
if( substrs.get(j).length()>=j-i && substrs.get(i).substring(0,j-i).equals(substrs.get(j).substring(0,j-i))){
++count;
for(int k=j+(j-i);k<len;k+=j-i){
System.out.println(i+" "+j+" "+k+" "+count);
if(substrs.get(k).length()>=j-i && substrs.get(i).substring(0,j-i).equals(substrs.get(k).substring(0,j-i))){
count++;
}else{
break;
}
}
if(count>maxCount){
maxCount = count;
substr = substrs.get(i).substring(0,j-i);
}
}
}
}
map.put(maxCount, substr);
return map;
}
public static void main(String[] args){
String str = "abcbcbcbc";
Map<Integer,String> rs = fun(str);
System.out.println(rs.toString());
}
}