string1中的最小长度窗口,其中string2是子序列

时间:2014-08-28 09:25:03

标签: algorithm window dynamic-programming dna-sequence subsequence

给出主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”的顺序

我不确定我是在想正确的方向,还是我完全不在 有没有已知的算法,或者有人知道任何方法吗?请建议 提前致谢。

3 个答案:

答案 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;
}