区分一组字符串的最短唯一子序列

时间:2016-08-12 11:12:46

标签: arrays algorithm substring subset bit

我有N个比特串(每个大小为M)X1 [0..M],...,XN [0..M]。我需要伪代码/算法来找到每个给定字符串中唯一的最小长度子序列(不一定是连续的)。例如,

如果字符串是011011,011000,010010,则每个字符串中的子序列[2,4](11,10,01)是不同的。或者子序列[2,4,5](111,100,010)。或者子序列[4,5](11,00,10) 但不是子序列[0,1,5](011,010,010)--->在每个字符串中都不是唯一的。

编辑:1 <= M <= 1000, 2 <= N <= 10
编辑:目前,我的解决方案是: 子序列的最小长度介于ceil(log2(N))N-1之间。  所以,伪代码将是:

for i = ceil(log2(N)) to N-1 :  
    check all subsequence of size i
    if any subsequence distinguish all N strings, return i

第一步可以通过生成所有组合mCi来完成。 第二步可以通过提取所有N个字符串的子序列并检查它们是否都是不同的来完成。 但是这种算法目前是指数复杂的。我想知道是否有更好的算法。

编辑:不,这不是功课。有人在接受采访时被问到了。

1 个答案:

答案 0 :(得分:0)

我认为这样的事情会起作用:

第一

create matriz A (mxm) and array B(m)
for each bit i from right to left, compute de decimal value of j word in A[i][j]
//that means A[i][j] holds the decimal value of word j until the i bit
in the same loop B[i] will hold if bit i from all words are the same.

如果B [i] =真,那就意味着我们不需要看那个位置,因为它什么也没说。

create deque D//to check if there is equal elements
create array C(m)
for each position P in [0...M] where B[i] = false :


for each bit i = P ... 0

   for each word j
        C[j] = C[j]*2 + word[j][i] //word[j][i] = word j in bit i

    bool finished = true;
    for each e in C:
        if(D.count(e) > 0) {
             finished = false;
             break;
        }
        else{
            D.add(e)
        }
    }
    if(finished) return range(P...i);
    D.clear()

not possible;

这个算法的作用是:从有用位置开始,它开始为它们创建单词的值,并且在你能够在双端队列中添加所有这些单词的时候(所有这些都是不同的),你就完成了它们不同的范围(范围是P - i + 1大小)。

你必须为B [i] = false的所有i运行它,所以在最坏的情况下它应该运行大约n³。

请注意,有一些优化可以在知道字符串数量及其大小的情况下完成,例如:如果有10个大小为3的字符串,则表示无法区分(因为大小不同,有10个不同的二进制文件) 3)。给定字符串数量,您只能搜索(连续或不连续)大小ceil(log(字符串数))。例如,5个字不能在一位中有所不同,它们在2位中不同,但是在3位时它们可以不同。