题目
求两个字符串有多少公共子串?
输入两个串s,t,例如
adasd
asddd
输出公共子串的个数
解析
求解有两个步骤
- 先找到一个字符串的所有子串(要记得去重)
- 然后再看这个子串能不能在另一个串中进行匹配
代码实现
代码过程
找到子串去重
public List<String> allSonStr(String s){
List<String> list= new ArrayList<>();
for (int i = 0; i <= s.length()-1; i++) {
for (int j = 0; j <= i; j++) {
list.add(s.substring(j,s.length()-i+j));
}
}
list = list.stream().distinct().collect(Collectors.toList());//去重
return list;
}
匹配我们用KMP算法
/**
* KMP 字符串匹配
*
* @param source
* @param target
* @return
*/
public static boolean strStr(String source, String target) {
if (target.length() == 0) {
return false;
}
// 记录前缀
int[] next = new int[target.length()];
getNext(next, target);
for (int i = 0, j = 0; i < source.length(); i++) {
while (j > 0 && source.charAt(i) != target.charAt(j)) {
j = next[j - 1];
}
if (source.charAt(i) == target.charAt(j)) {
j++;
}
if (j == target.length()) {
return true;
}
}
return false;
}
/**
* 计算目标串 target的前缀
*
* @param next
* @param target
*/
private static void getNext(int[] next, String target) {
int len = target.length();
next[0] = 0;
for (int i = 1, j = 0; i < len; i++) {
while (j > 0 && target.charAt(i) != target.charAt(j)) {
j = next[j - 1];
}
if (target.charAt(i) == target.charAt(j)) {
j++;
}
next[i] = j;
}
}
最终代码
package com.interview.writeexam.zhitong;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
public class Main1 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.next();
String t = in.next();
List<String> list = new ArrayList<>();
int result = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j <= i; j++) {
String strTmp = s.substring(j,s.length()-i+j);
list.add(strTmp);
}
}
list = list.stream().distinct().collect(Collectors.toList());
for (int i = 0; i < list.size(); i++) {
if (strStr(t,list.get(i))){
result++;
}
}
System.out.println(result);
}
/**
* KMP 字符串匹配
*
* @param source
* @param target
* @return
*/
public static boolean strStr(String source, String target) {
if (target.length() == 0) {
return false;
}
// 记录前缀
int[] next = new int[target.length()];
getNext(next, target);
for (int i = 0, j = 0; i < source.length(); i++) {
while (j > 0 && source.charAt(i) != target.charAt(j)) {
j = next[j - 1];
}
if (source.charAt(i) == target.charAt(j)) {
j++;
}
if (j == target.length()) {
return true;
}
}
return false;
}
/**
* 计算目标串 target的前缀
*
* @param next
* @param target
*/
private static void getNext(int[] next, String target) {
int len = target.length();
next[0] = 0;
for (int i = 1, j = 0; i < len; i++) {
while (j > 0 && target.charAt(i) != target.charAt(j)) {
j = next[j - 1];
}
if (target.charAt(i) == target.charAt(j)) {
j++;
}
next[i] = j;
}
}
}