在MATLAB中索引一个更大的向量

时间:2019-01-21 11:39:59

标签: matlab

我试图找到较大矢量中较小矢量的索引位置。

我已经使用strfindbind2dec解决了这个问题, 但我不想使用strfind,也根本不想转换为字符串或deciamls。

给出更长的向量

a=[1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1];

我想在a

中找到较小向量 b的索引
b=[1,1,1,0,0,0];

我希望找到结果

result=[15,16,17,18,19,20];

谢谢

4 个答案:

答案 0 :(得分:7)

以下是使用一维卷积的解决方案。它可能会找到多个匹配项,因此start拥有子矢量的开始索引:

f = flip(b);

idx = conv(a,f,'same')==sum(b) & conv(~a,~f,'same')==sum(~b);

start = find(idx)-ceil(length(b)/2)+1;

result = start(1):start(1)+length(b)-1;

答案 1 :(得分:4)

使用for循环的解决方案:

a=[1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1];
b=[1,1,1,0,0,0];
c = [];
b_len = length(b)
maxind0 = length(a) - b_len + 1 %no need to search higher indexes 

for i=1:maxind0
  found = 0;
  for j=1:b_len
    if a(i+j-1) == b(j)
      found = found + 1;
    else
      break;
    end
  end

  if found == b_len  % if sequence is found fill c with indexes
    for j=1:b_len
      c(j)= i+j-1;
    end

    break
  end
end

c %display c

答案 2 :(得分:3)

是否需要提高计算效率?

效率不高但解决方案很短:

a=[1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1];;
b=[1,1,1,0,0,0];
where = find(arrayfun(@(n) all(a(n+1:n+length(b))==b),0:length(a)-length(b)));

...给您15。您的result将成为向量where:where+length(b)-1

编辑:我尝试过,并且我已纠正。这是带有循环的版本:

function where = find_sequence(a,b)

na = 0;
where = [];
while na < length(a)-length(b)
    c = false;
    for nb = 1:length(b)
        if a(na+nb)~=b(nb)
            na = na + 1;  % + nb
            c = true;                        
            break
        end

    end
    if ~c
        where = [where,na+1];
        na = na + 1;
    end   
end

尽管它的循环以及在Matlab中的不良声誉,但速度要快得多:

a = round(rand(1e6,1));
b = round(rand(10,1));

tic;where1 = find(arrayfun(@(n) all(a(n+1:n+length(b))==b),0:length(a)-length(b)));toc;
tic;where2 = find_sequence(a,b);toc;


>> test_find_sequence
Elapsed time is 4.419223 seconds.
Elapsed time is 0.042969 seconds.

答案 3 :(得分:2)

使用for的更整洁的方法看起来像这样,不需要内部检查循环,因为我们可以使用all将其向量化...

a = [1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1];
b = [1,1,1,0,0,0];

idx = NaN( size(b) ); % Output NaNs if not found
nb = numel( b );      % Store this for re-use

for ii = 1:numel(a)-nb+1
    if all( a(ii:ii+nb-1) == b )
        % If matched, update the index and exit the loop
        idx = ii:ii+nb-1;
        break
    end
end

输出:

idx = [15,16,17,18,19,20]

请注意,与某些嵌套的解决方案相比,我觉得这更容易理解,但不一定更快,因为每次都对b中的所有元素进行比较。