算法场景应用:求两个字符串有多少公共子串?

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法场景应用:求两个字符串有多少公共子串?相关的知识,希望对你有一定的参考价值。

文章目录

题目

求两个字符串有多少公共子串?

输入两个串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;
        
    


以上是关于算法场景应用:求两个字符串有多少公共子串?的主要内容,如果未能解决你的问题,请参考以下文章

求两个输入的字符串的最长公共子串

寻找最长公共子串(高分)

求两个字符串的最长公共子串,要求输入两个字符串,输出他们的最长公共子串,包括长度。

面试宝典_Python.常规算法.0002.输出任意两个字符串中最长公共子串?

java求最大公共子串

java求最长公共子串的长度