字符串间的距离比较+查找公共子串长度——通过二维数组比较

**【题目】**对于不同的字符串,我们希望能有办法判断相似程度,我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作方法如下:

1 修改一个字符,如把“a”替换为“b”。

2 增加一个字符,如把“abdd”变为“aebdd”。

3 删除一个字符,如把“travelling”变为“traveling”。

比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加和减少一个“g”的方式来达到目的。上面的两种方案,都只需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,相似度为1/2=0.5.

给定任意两个字符串,你是否能写出一个算法来计算出它们的相似度呢?

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s1 = sc.next();
            String s2 = sc.next();
            char[] c1 = s1.toCharArray();
            char[] c2 = s2.toCharArray();
            int[][] dp = new int[s1.length()+1][s2.length()+1];
            
            for(int row=1;row<=s1.length();row++){
                dp[row][0]=row;
            }
            for(int col=1;col<=s2.length();col++){
                dp[0][col]=col;
            }
            for(int row=1;row<=s1.length();row++){
                for(int col=1;col<=s2.length();col++){
                    if(c1[row-1]==c2[col-1]){
                        dp[row][col]=dp[row-1][col-1];//相应位置相同则不+1
                    }else{
                        //不同则+1
                        int min1=Math.min(dp[row-1][col],dp[row][col-1])+1;
                        dp[row][col]=Math.min(min1,dp[row-1][col-1]+1);
                    }
                }
            }
            System.out.println("1/"+(dp[s1.length()][s2.length()]+1));
        }
    }
}

【相似补充】公共子字符串长度

【题目】计算两个字符串的最大公共子串的长度,字符不区分大小写
在这里插入图片描述

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String input = sc.nextLine();
            String[] s = input.split(" ");
            String s1 = s[0];
            String s2 = s[1];
            //不区分大小写
            String str1 = s1.toUpperCase();
            String str2 = s2.toUpperCase();
            char[] c1 = str1.toCharArray();
            char[] c2 = str2.toCharArray();
            //用一个二维数组来对比两个一维字符串数组,相同则该位数字在前一个基础上+1
            int[][] dp = new int[c1.length+1][c2.length+1];
            //先将二维数组的第一行和第一列给
            for(int i=0;i<c1.length;i++){
                if(c1[i]==c2[0]){
                    dp[i][0]=1;
                }
            }
            
            for(int j=1;j<c2.length;j++){
                if(c2[j]==c1[0]){
                    dp[0][j]=1;
                }
            }
            int max=0;
            for(int i=1;i<c1.length;i++){
                for(int j=1;j<c2.length;j++){
                    if(c1[i]==c2[j]){
                        dp[i][j]=dp[i-1][j-1]+1;
                    }else{
                        dp[i][j]=0;//不同则清零,下一个位置重新开始算
                    }
                    max = Math.max(max,dp[i][j]);
                }
            }
            System.out.println(max);
        }
		sc.close();
    }
}

【查找最长公共子串】

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
在这里插入图片描述

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s1 = sc.nextLine();
            String s2 = sc.nextLine();
            System.out.println(fun(s1,s2));
        }
        sc.close();
    }
    
    public static String fun(String s1,String s2){
        if(s1.length()>s2.length()){//将其变成s1短,s2长
            String temp = s1;
            s1 = s2;
            s2 = temp;
        }
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        int[][] dp = new int[s1.length()][s2.length()];
        for(int i=0;i<s1.length();i++){
            if(c1[i]==c2[0]){
                dp[i][0]=1;
            }
        }
        for(int j=1;j<s2.length();j++){
            if(c1[0]==c2[j]){
                dp[0][j]=1;
            }
        }
        int max=0;
        for(int i=1;i<s1.length();i++){//先找出最大长度max
           for(int j=1;j<s2.length();j++){
               if(c1[i]==c2[j]){
                  dp[i][j] = dp[i-1][j-1]+1;
               }else{
                  dp[i][j] = 0;
               }
               max = Math.max(max,dp[i][j]);
           }
        }
        //一次对比两个字符串中长为max的子串,找到短字符串s1中的第一个公共子串
        for(int i=0;i<s1.length()-max+1;i++){
            String ss1 = s1.substring(i,i+max);
            for(int j=0;j<s2.length()-max+1;j++){
                String ss2 = s2.substring(j,j+max);
                if(ss1.equals(ss2)){
                    return ss1;
                }
            }
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值