我有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个字符串的子序列并检查它们是否都是不同的来完成。 但是这种算法目前是指数复杂的。我想知道是否有更好的算法。
编辑:不,这不是功课。有人在接受采访时被问到了。答案 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位时它们可以不同。