華爲OJ——計算字符串的相似度

題目描述

  對於不同的字符串,我們希望能有辦法判斷相似程度,我們定義了一套操作方法來把兩個不相同的字符串變得相同,具體的操作方法如下:
1 修改一個字符,如把“a”替換爲“b”。
2 增加一個字符,如把“abdd”變爲“aebdd”。
3 刪除一個字符,如把“travelling”變爲“traveling”。
  比如,對於“abcdefg”和“abcdef”兩個字符串來說,我們認爲可以通過增加和減少一個“g”的方式來達到目的。上面的兩種方案,都只需要一次操作。把這個操作所需要的次數定義爲兩個字符串的距離,而相似度等於“距離+1”的倒數。也就是說,“abcdefg”和“abcdef”的距離爲1,相似度爲1/2=0.5.
  給定任意兩個字符串,你是否能寫出一個算法來計算出它們的相似度呢?

  • 請實現如下接口
    /* 功能:計算字符串的相似度
     * 輸入:pucAExpression/ pucBExpression:字符串格式,如: “abcdef”
     * 返回:字符串的相似度,相似度等於“距離+1”的倒數,結果請用1/字符串的形式,如1/2
     */
    public static String calculateStringDistance(String expressionA, String expressionB)
    {
      /* 請實現*/
      return null;
    }

  • 約束:
    1、PucAExpression/ PucBExpression字符串中的有效字符包括26個小寫字母。
    2、PucAExpression/ PucBExpression算術表達式的有效性由調用者保證;
    3、超過result範圍導致信息無法正確表達的,返回null。

  • 輸入描述:
    輸入兩個字符串

  • 輸出描述:
    輸出相似度,string類型
  • 示例1
    輸入
      abcdef
      abcdefg
    輸出
      1/2

實現代碼

思路:

  這道題其實簡單的理解就是爲了求字符串的最小編輯代價,也是一個經典的動態規劃題,複雜度O(M*N)

  • 1.求解狀態轉移矩陣dp[M + 1][N + 1],dp[i][j] 的值代表的是str1[0…i-1]編輯爲str2[0…j-1]的最小代價。

  • 2.計算過程:
    1)dp[0][0] = 0,表示str1空的字串編輯爲str2空的字串代價爲0。
    2)矩陣dp第一列即爲dp[0…M-1][0],dp[i][0] 表示str1[0…i-1]編輯爲空串的最小代價,所以就是將str1[0..M-1]的字符刪掉的代價所以dp[i][0] = i;
    3) 同2),那str2[0…j-1]編輯的代價,dp[0][j] = j;
    4) 接下來的位置就按照從左到右,從上到下來計算,dp[i][j]的值來至於下面的幾種情況:
    ①str1[0…i-1]可以先編輯爲str1[0..i-2],也就是刪除字符str1[i-1],然後由str1[0..i-2]編輯爲str2[0…j-1],dp[i-1][j]表示str1[0..i-2]編輯爲str2[0…j-1]的最小代價,
    那麼dp[i][j]可能等於dp[i -1][j] + 1;
    ②str1[0…i-1]可以先編輯爲str1[0..i-2],然後將str2[0..j-2]插入字符str2[j-1],編輯成str2[0…j-1],dp[i][j-1]表示str1[0..i-1]編輯成str2[0…j-2]的最小代價,
    那麼dp[i][j] 可能等於dp[i][j-1] + 1;
    ③ 如果str1[i - 1]!=str2[j-1] ,那麼先把str1[0..i-1]中的str1[0..i-2]的部分邊長str2[0..j-2],然後把字符str1[i-1]替換爲str2[j-1],這樣str1[0..i-1]就編輯成爲str2[0…j-1]了,dp[i - 1][j - 1]表示
    str1[0..i-2]編輯爲str2[0..j-2]的最小代價,那麼dp[i ][j]可能等於dp[i - 1][j - 1] + 1;
    ④如果str1[i - 1]==str2[j-1] ,那麼先把str1[0..i-1]中的str1[0..i-2]的部分邊長str2[0..j-2],因爲此時 str1[i - 1]==str2[j-1] ,所以str1[0..i-1]已經編輯爲str2[0..j-1]了,dp[i - 1][j - 1]表示str1[0..i-2]編輯爲str2[0..j-2]的最小代價, 那麼dp[i ][j]可能等於dp[i - 1][j - 1]

上述的4中情況取最小值,dp的最右下角就是最終結果,即最小編輯代價。

package cn.c_shuang.demo76;

import java.util.Scanner;
/**
 * 計算字符串的相似度
 * @author Cshuang
 *
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String strA=in.nextLine();
            String strB=in.nextLine();
            int result = caculate(strA,strB)+1;
            System.out.println("1/"+result);
        }
        in.close();
    }

    private static int caculate(String a, String b) {
        int n = a.length();
        int m = b.length();
        char[] aCh = a.toCharArray();
        char[] bCh = b.toCharArray();
        int[][] dp = new int[n+1][m+1];
        if(n==0)
            return m;
        if(m==0)
            return n;
        for(int i=0;i<n+1;i++){//初始化
                dp[i][0]=i;
        }
        for(int i=0;i<m+1;i++){//初始化
                dp[0][i]=i;
        }

        for(int i=1;i<n+1;i++){
            for(int j=1;j<m+1;j++){
                if(aCh[i-1]==bCh[j-1])
                    dp[i][j]=dp[i-1][j-1];
                else{
                    dp[i][j]=Math.min(dp[i-1][j]+1, Math.min(dp[i][j-1]+1, dp[i-1][j-1]+1));
                }
            }
        }
        return dp[n][m];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章