给出主DNA序列(字符串)(比如说string1)和另一个要搜索的字符串(比如说string2)。你必须在string1中找到最小长度窗口,其中string2是子序列
string1 =“abcdefababaef”
string2 =“abf”
我想到的方法,但似乎没有起作用:
1.使用最长公共子序列(LCS)方法并检查(LCS的长度= string2的长度)。但这会告诉我string2是否作为子序列存在于string1中,而不是最小的窗口
2. KMP算法,但不知道如何修改它。
3.准备string1中的{characters:characters of characters}字符串的映射。喜欢:
{a:0,6,8,10
b:1,7,9
f:5,12}
然后一些方法找到最小窗口,仍然保持“abf”的顺序
我不确定我是在想正确的方向,还是我完全不在 有没有已知的算法,或者有人知道任何方法吗?请建议 提前致谢。
答案 0 :(得分:0)
您可以执行 LCS ,并使用 LCS 结果的DP表上的递归查找String1
String2
中的所有最大子序列。然后计算每个 LCS 的窗口长度,你可以得到它的最小值。如果分支已超过当前最小窗口的大小,您也可以停止分支。
检查读出所有LCS : -
http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
答案 1 :(得分:0)
动态编程! 这是一个C实现
#include <iostream>
#include <vector>
using namespace std;
int main() {
string a, b;
cin >> a >> b;
int m = a.size(), n = b.size();
int inf = 100000000;
vector < vector < int > > dp (n + 1, vector < int > (m + 1, inf)); // length of min string a[j...k] such that b[i...] is a subsequence of a[j...k]
dp[n] = vector < int > (m + 1, 0); // b[n...] = "", so dp[n][i] = 0 for each i
for (int i = n - 1; i >= 0; --i) {
for (int j = m - 1; j >= 0; --j) {
if(b[i] == a[j]) dp[i][j] = 1 + dp[i+1][j+1];
else dp[i][j] = 1 + dp[i][j+1];
}
}
int l, r, min_len = inf;
for (int i = 0; i < m; ++i) {
if(dp[0][i] < min_len) {
min_len = dp[0][i];
l = i, r = i + min_len;
}
}
if(min_len == inf) {
cout << "no solution!\n";
} else {
for (int i = l; i < r; ++i) {
cout << a[i];
}
cout << '\n';
}
return 0;
}
答案 2 :(得分:0)
我在CareerCup上发现了一个类似的面试问题,唯一不同的是它是一个整数数组而不是字符。我借用了一个想法并进行了一些更改,如果您在阅读此C ++代码后有任何疑问,请告诉我。
我在这里要做的是:for
函数中的main
循环用于遍历给定数组的所有元素,并找到我遇到子数组的第一个元素的位置,一旦找到,我调用find_subsequence
函数,在那里我递归地将给定数组的元素与子数组相匹配保留元素的顺序。最后,find_subsequence
返回位置,我计算子序列的大小。
请原谅我的英语,希望我能更好地解释一下。
#include "stdafx.h"
#include "iostream"
#include "vector"
#include "set"
using namespace std;
class Solution {
public:
int find_subsequence(vector<int> s, vector<int> c, int arrayStart, int subArrayStart) {
if (arrayStart == s.size() || subArrayStart ==c.size()) return -1;
if (subArrayStart==c.size()-1) return arrayStart;
if (s[arrayStart + 1] == c[subArrayStart + 1])
return find_subsequence(s, c, arrayStart + 1, subArrayStart + 1);
else
return find_subsequence(s, c, arrayStart + 1, subArrayStart);
}
};
int main()
{
vector<int> v = { 1,5,3,5,6,7,8,5,6,8,7,8,0,7 };
vector<int> c = { 5,6,8,7 };
Solution s;
int size = INT_MAX;
int j = -1;
for (int i = 0; i <v.size(); i++) {
if(v[i]==c[0]){
int x = s.find_subsequence(v, c, i-1, -1);
if (x > -1) {
if (x - i + 1 < size) {
size = x - i + 1;
j = i;
}
if (size == c.size())
break;
}
}
}
cout << size <<" "<<j;
return 0;
}