標題清洗引起的算法(兩個字符串的最長公共子串)

前言

在作聲音標題清洗的時候,須要將專輯的標題和聲音的標題對比,若是他們的最長公共字符串長度大於三,則清除聲音中的最長公共字符串,不然不清除。java

解析

  1. 把聲音標題的字符串,放入x軸,把專輯標題的字符串,放入y軸。以下圖一
圖一
  1. 當x爲1的時候,爲 "平",那麼對應的 y軸上的字符,若是相同的話設置爲1。 以下圖二

圖二
  1. 當y爲1的時候,爲 "平", 那麼對應的 x軸上的字符,若是相同的話設置爲1。 正則表達式

  2. 當x爲2的時候,爲 "凡", 那麼對應 y軸上的字符,若是相同的話,查看 x-1,y-1 對應的數字大小加1,標註後以下圖三 算法

圖三
  1. 當x爲3的時候, 爲 "的",那麼對應y軸上的字符,若是相同的話,查看 x-1,y-1 對應的數字大小加1,標註後以下圖四
圖四
。。。。。

依次往下走,直到x上沒有字符串爲止。 這是一個比較經典的動態規劃算法,可以瞭解他的狀態轉移方程爲 dp[i][j]=dp[i][j] + 1 時間複雜度爲 O(nm);spa

具體代碼以下

/** * @Author ouyangkang * @Description 清除兩個字符串的最長公共子串,若是長度小於3 不清除 * @Date 10:45 2019-10-31 * @param albumTitle * @param trackTitle * @return java.lang.String **/
    private static String cleanTrackTitleFromAlbumTitle(String albumTitle, String trackTitle){

        if (StringUtils.isBlank(albumTitle) || StringUtils.isBlank(trackTitle)){
            return trackTitle;
        }
        Map<String, Integer> map = getLongestCommonSubstring(albumTitle, trackTitle);
        Integer len = map.get("len");
        Integer start = map.get("start");
        if (len > 3){
            start += 1;
            return trackTitle.replace(trackTitle.substring(start - len,start), "");
        }else {
            return trackTitle;
        }
    }

 /** * @Author ouyangkang * @Description 獲取兩個字符串最長公共子串 * @Date 16:01 2019-10-31 * @param albumTitle * @param trackTitle * @return java.util.Map<java.lang.String,java.lang.Integer> **/
    private static Map<String, Integer> getLongestCommonSubstring(String albumTitle, String trackTitle){
        Map<String, Integer> map = new HashMap<>();
        // 最長公共子串大小
        int len = 0;
        // 子串座標
        int start = 0;
        // 最長公共子串大小 爲 dp[i][j] = dp[i-1][j-1] + 1;
        int[][] dp = new int[albumTitle.length()][trackTitle.length()];
        for (int i = 0; i < albumTitle.length(); i++){
            for (int j = 0; j< trackTitle.length();j++){
                if (i==0 && albumTitle.charAt(0)== trackTitle.charAt(j)){
                    dp[0][j] = 1;
                    continue;
                }

                if (j==0 && albumTitle.charAt(i) == trackTitle.charAt(0)){
                    dp[i][0] = 1;
                    continue;
                }

                if(albumTitle.charAt(i) == trackTitle.charAt(j)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                    if (dp[i][j] > len){
                        len = dp[i][j];
                        start = j;
                    }
                }
            }
        }
        // 記錄長度
        map.put("len",len);
        // 記錄聲音標題的座標
        map.put("start",start);
        return map;
    }
複製代碼

調用 cleanTrackTitleFromAlbumTitle方法,入參爲 "平凡的世界", "平凡的時間01"。返回的字符串爲 01code

總結

可以在平常開發中,寫一寫算法,並應用到程序中,不是curd,也是比較有意思的一件事,清洗的過程是很複雜的,這只是其中一步清洗,其餘的清洗涉及到一些正則表達式。一開始寫了些可以實現功能的正則,可是在同事的提醒下,發現了很涉及到正則的回溯。emmmm.. 這就是另說了,下次博客補上。cdn

相關文章
相關標籤/搜索