動態規划:給出兩個字符串s1和s2,返回其中最大的公共子串


求公共子字符串問題(連續的)

這個題目是當時遠景能源公司現場筆試的一道題目,當時根本就不知道動態規划是什么鬼,直接上來就暴力求解,面試官很諂媚的問我,你這能求出來嗎?當時很年輕的說,能啊!現在想,當時哪來的自信和逗比勇氣說這大話。。。在《進軍硅谷》這本書上看到原題,我是懵逼,怎么想出這種解答出來的,下面直接上思路和代碼。

思路:

定義二維數組dp[i][j]記錄最大公共子串的長度,

  • 若要返回字符串可以用s1.substring(i-dp[i][j]+1, i+1)
  • 當s[i]==s[j]時,dp[i][j]=dp[i-1][j-1]+1;
  • 當s[i]!=s[j]時,dp[i][j]=0;

有點類似於數學歸納法

方案:

  • 首先考慮空或者長度為0的情況,直接返回"";
  • 然后進入雙重循環:
  • 1.利用charAt(int index)方法來比較兩個字符串相等的時機
  • 2.考慮邊界情況,兩個字符串中有一個是起始為0就相等,則dp[i][j]=1
  • 3.除了邊界情況,其他最大字符串長度為dp[i][j]=dp[i-1][j-1]+1;
  • 4.不斷的替換掉最大的長度並返回公共子串
  • 最后循環結束后,返回最大的公共子串
 1     public static String maxCommonString(String s1, String s2) {
 2         String res = "";
 3         if (s1 == null || s1.length() == 0 || s2 == null || s2.length() == 0)
 4             return res;
 5         int max = 0, m = s1.length(), n = s2.length();
 6         int[][] dp = new int[m][n]; // 定義一個二維數組記錄最大公共子串的長度
 7         // 計算到s1的第i個字符和s2的第j個字符為止的最大公共子串長度
 8         for (int i = 0; i < m; i++) {
 9             for (int j = 0; j < n; j++) {
10                 // 如果s1字符串在i處和s2字符串在j處有字符相同,進入if代碼塊中
11                 if (s1.charAt(i) == s2.charAt(j)) {
12                     if (i == 0 || j == 0)
13                         dp[i][j] = 1;// 邊界的情況
14                     else
15                         dp[i][j] = dp[i - 1][j - 1] + 1;// 加上當前長度
16                     // 記錄最大長度和子串
17                     if (dp[i][j] > max) {
18                         max = dp[i][j];
19                         res = s1.substring(i - dp[i][j] + 1, i + 1);// substring()左閉右開
20                     }
21                 }
22             }
23         }
24         return res;
25     }

動態規划介紹

動態規划算法一般是基於一個遞推公式(如上面的當s[i]==s[j]時,dp[i][j]=dp[i-1][j-1]+1;)以及一個或多個初始狀態(當s[i]!=s[j]時,dp[i][j]=0;),當前子問題其實是由上一次子問題的解推算出來的。
【附帶福利:markdown每行縮進的方式】

半方的空白&ensp;或&#8194;
全方的空白&emsp;或&#8195;
不斷行的空白格&nbsp;或&#160;
(分號都是英文格式的)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找 【python】實例-python實現兩個字符串中最大的公共子串 兩個字符串的最長公共子串求法(C++、動態規划) 寫一個函數,實現兩個字符串的比較。即實現strcmp函數,s1=s2時返回0,s1!=s2時返回二者第一個不同字符的ASCII值。 給出兩個字符串(可能包含空格),找出其中最長的公共連續子串,輸出其長度。 編寫一個程序,將兩個字符串s1和s2比較,如果s1 > s2,輸出一個整數;若s1 = s2,輸出0;若s1 < s2,輸出一個負數。不要用strcpy函數。兩個字符串用gets函數讀入。輸出的正數或負數的絕對值應是相比較的兩個字符串相對應字符的ASCII碼的差值。 8、將兩個字符串s1,s2進行比較,如果s1>s2,則輸出一個正數。如果s1 = s2,輸出零。如果s1 < s2, 輸出一個負數,不用strcmp函數,輸出的正數或者負數的絕對值應該是比較兩字符串相應字符的ascii碼的差值。 編寫一個程序,將連個字符串s1和s2比較,如果s1 > s2,輸出一個整數;若s1 = s2,輸出0;若s1 < s2,輸出一個負數。不要用strcpy函數。兩個字符串用gets函數讀入。輸出的正數或負數的絕對值應是相比較的兩個字符串相對應字符的ASCII碼的差值。例如,"A"和“C”相比,由於"A" < "C",應輸出負數,同時由於‘A’與‘C’的ASCII碼差值為2,因此應輸出"-2" 給出兩個字符串,求出其最大的相同子串。 java 算法之 兩個字符串中最大相同的子串 獲取兩個字符串中最大的相同子串
 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM