识别重复序列中的差距

时间:2013-10-31 15:39:52

标签: algorithm matlab sequences

我有一个载体,应该包含从0到11的n个序列

A = [00;01;02;03;04;05;06;07;08;09;10;11;00;01;02;03;04;05;06;07;08;09;10;11]

我想检查序列“00 - 11”是否始终受到尊重(没有缺失值)。

例如

A =[00;01;02;  04;05;06;07;08;09;10;11;00;01;02;03;04;05;06;07;08;09;10;11] 

(在第3位缺​​少03) 对于每个缺失的值,我希望在另一个向量中备份此信息

missing=
 [value_1,position_1;
 value_2, position_2;
 etc, etc]

你能帮助我吗?

3 个答案:

答案 0 :(得分:2)

当然,我们知道最后一个元素必须是11,所以我们已经可以检查这个并让我们的生活更容易测试所有以前的元素。我们确保A是11终止的,因此“元素改变”方法(下面)将是有效的。请注意,开头也是如此,但更改A会导致索引混乱,因此我们稍后会更好地处理。

missing = [];
if A(end) ~= 11
    missing = [missing; 11, length(A) + 1];
    A = [A, 11];
end

然后我们可以计算从一个元素到另一个元素的变化dA = A(2:end) - A(1:end-1);,并确定差距位置idx_gap = find((dA~=1) & (dA~=-11));。现在我们需要使用ev来扩展所有缺失的索引和期望值,以获得期望值。可以从上一个值中获取ev,如

for k = 1 : length(idx_gap)
    ev = A(idx_gap(k));

现在,要填写的元素数量是该位置的变化dA减1(因为一个意味着没有间隙)。请注意,如果在段之间的边界处存在间隙,则可以包裹,因此我们使用模数。

    for n = 1 : mod(dA(idx_gap(k)) - 1, 12)
        ev = mod(ev + 1, 12);
        missing = [missing; ev, idx_gap(k) + 1];
    end
end

作为测试,考虑A = [5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 0 1 2 3 4 6 7 8]。这是一种情况,从一开始的特殊初始化将触发,记忆缺失的11,并将A更改为[5 6 ... 7 8 11]。 missing然后会产生

11    24    % recognizes improper termination of A.
11     7
 0     7    % properly handles wrap-over here.
 1     7
 2     7
 5    21    % recognizes single element as missing.
 9    24
10    24

应该是你期望的。现在缺少的是A的开头,所以让我们说missing = [0 : A(1) - 1, 1; missing];来完成列表。

答案 1 :(得分:1)

这将为您提供缺失值及其在完整序列中的位置:

N = 11; % specify the repeating 0:N sub-sequence
n = 3; % reps of sub-sequence
A = [5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 0 1 2 3 4 6 7 8]'; %' column from s.bandara

da = diff([A; N+1]); % EDITED to include missing end
skipLocs = find(~(da==1 | da==-N));
skipLength = da(skipLocs)-1;
skipLength(skipLength<0) = N + skipLength(skipLength<0) + 1;
firstSkipVal = A(skipLocs)+1;

patchFun = @(x,y)(0:y)'+x - (N+1)*(((0:y)'+x)>N);
patches = arrayfun(patchFun,firstSkipVal,skipLength-1,'uni',false);
locs = arrayfun(@(x,y)(x:x+y)',skipLocs+cumsum([A(1); skipLength(1:end-1)])+1,...
    skipLength-1,'uni',false);

然后将它们放在一起,包括开头的任何缺失值:

>> gapMap = [vertcat(patches{:}) vertcat(locs{:})-1]; % not including lead
>> gapMap = [repmat((0 : A(1) - 1)',1,2); gapMap] %' including lead
gapMap =
     0     0
     1     1
     2     2
     3     3
     4     4
    11    11
     0    12
     1    13
     2    14
     5    29
     9    33
    10    34
    11    35

第一列包含缺失值。第二列是假设完整序列中从0开始的位置。

>> Afull = repmat(0:N,1,n)
>> isequal(gapMap(:,1), Afull(gapMap(:,2)+1)')
ans =
     1

答案 2 :(得分:0)

虽然这不能完全解决您的问题,但您可以确定缺失值的位置,或者连续缺失值组的位置,如下所示:

ind = 1+find(~ismember(diff(A),[1 -11]));

ind给出了当前序列A的位置,而不是已完成的序列。

例如,使用

A =[00;01;02;  04;05;06;07;08;09;10;11;00;01;02;03;    ;06;07;08;09;10;11]; 

这给出了

>> ind = 1+find(~ismember(diff(A),[1 -11]))

ind =

     4
    16