1.公共子串可不连续
1.最长公共子序列,可看这道题目,使用动态规划的做法
2.判断一个字符串是否是另一个的子序列
static boolean isSubString(String s, String t){
int i = 0;
int j = 0;
while(i < s.length() && j < t.length()){
if(s.charAt(i) == t.charAt(j)){
j++;
}
//不管是否相等,s都要往后遍历一个字符
i++;
}
//最后看j是否与t长度相等即可判断出t是否是s的不连续子串
return j == t.length();
}
2.公共子串连续
1.求两字符串最长公共子串
(1)
static String maxSubstring(String str1, String str2){
// 参数检查
if(str1 == null || str2 == null){
return null;
}
if(str1.equals("") || str2.equals("")){
return null;
}
// 二者中较长的字符串
String max = str1.length() > str2.length() ? str1 : str2;
// 二者中较短的字符串
String min = str1.length() < str2.length() ? str1 : str2;
String current = "";
// 遍历较短的字符串,并依次减少短字符串的字符数量,判断长字符是否包含该子串
for(int i=0; i<min.length(); i++){
for(int begin=0, end=min.length()-i; end<=min.length(); begin++, end++){
current = min.substring(begin, end);
if(max.contains(current)){
return current;
}
}
}
return null;
}
(2)动态规划的做法
static String maSubString(String str1, String str2){
if (str1 == null || str1.length() == 0 || str2 == null || str2.length() == 0){
return null;
}
int[][] dp = new int[str1.length()][str2.length()];
int maxLen = 0;
int endIndex = 0;
for (int i = 0; i < str1.length(); i++) {
for (int j = 0; j < str2.length(); j++) {
//当前两字符相等
if (str1.charAt(i) == str2.charAt(j)){
if (i == 0 || j == 0){
//某字符串开头第一个字符,所以长度只能是1
dp[i][j] = 1;
}else {
dp[i][j] = dp[i-1][j-1] + 1;
}
}else {
dp[i][j] = 0;
}
if (dp[i][j] > maxLen){
maxLen = dp[i][j];
//记录末尾下标,记录i或j都可,i最后返回str1的子串,j反之
endIndex = i;
}
}
}
return str1.substring(endIndex-maxLen+1, endIndex+1);
}