找出最接近的相似串(DP思想)
生活随笔
收集整理的這篇文章主要介紹了
找出最接近的相似串(DP思想)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:找出最接近的相似串
假設從一個串變化成另一個串所允許的操作只有兩種:插入一個字符或者刪除一個字符。無論是插入還是刪除一個符號,均算作一次操作。一般情況下,度量兩個串S1和S2的相似性,可以通過從一個串變換成另一個串所需要的最少操作次數來衡量,需要的操作次數越少,則越相似。現給你一個串S,和一個串的集合T,讓你找出集合T中與S最相似的串。
測試輸入:
abcd
4
abd
abdc
abed
aebcd
預期輸出:
abd
aebcd
思想:
這個題的實質就是求從一個字符串變為另一個字符串所需要的步驟數。下面我以從abcd變為baccdba的過程(也是從baccdba變為abcd)為例。列一個表如下,表示從a->b, a->ba, a -> bac … ab ->b, ab -> ba, ba->bac … … 的步驟數。
可以發現:1.如果橫豎的字符一樣,則a[i][j] = a[i-1][j-1],原因是相當于再沒有加這一列字符的情況下加上了這個字符,而又直接得到了目標字符串,所以不需要變化。如下圖所示:
2.如果橫豎字符不一樣,則a[i][j] = min(a[i-1][j] + 1,a[i][j-1] + 1),原因是相當于直接在已得字符串后面直接加上該字符,即操作數加一,或者減去該列的字符后直接得目標字符串,也相當于操作數加一。
具體代碼如下:
#include <iostream>
#include <cstring>
#include<string>
#include<algorithm>
using namespace std;string s;
int n;
string a;
int p[21][21];
int MIN = 1e7;
string ma[10];
int N = 0;void Similar()
{cin >> s >> n;for(int i = 0; i < n; i++){cin >> a;for(int k = 0; k < s.size(); k++)p[0][k] = k;for(int k = 0; k < a.size(); k++)p[k][0] = k;for(int k = 1; k <= s.size(); k++){for(int j = 1; j <= a.size(); j++){if(s[k] == a[j])p[k][j] = p[k-1][j-1];else{p[k][j] = min(p[k-1][j]+1,p[k][j-1]+1);}}}if(MIN > p[s.size()][a.size()]){MIN = p[s.size()][a.size()];ma[0] = a;N = 0;}else if(MIN==p[s.size()][a.size()]){N++;ma[N] = a; }} for(int i = 0; i <= N; i++){cout << ma[i] << endl;}
}int main()
{Similar();
}
總結
以上是生活随笔為你收集整理的找出最接近的相似串(DP思想)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一切浮云下一句是什么呢?
- 下一篇: HDOJ-2062 :Subset se