【问题标题】:Find regions of contiguous zeros in a binary array在二进制数组中查找连续零的区域
【发布时间】:2018-04-17 15:12:35
【问题描述】:

我有

x=[ 1 1 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1]

我想找出所有连续超过 5 个零的区域。我想找到它开始和停止的索引。

在这种情况下,我想要这个:c=[12 18]。我可以使用 for 循环来做到这一点,但我想知道是否有更好的方法,至少要找出是否有一些区域出现了这个“掩码”(mask=[0 0 0 0 0])。

【问题讨论】:

  • 如果 x 中存在多个零区域,输出会是什么?
  • 听起来像是一个经典的卷积问题。只需使用conv,选择最大值。
  • 您想要c=[12 18] 还是c=[12 17],因为该序列中的最后一个0 位于元素17。所以是18 故意还是错字?
  • 虽然这不一定是重复的,但与经典的island of zeros问题有一些相似之处。

标签: arrays matlab vector


【解决方案1】:

基于卷积的方法:

n = 5;
x = [0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 1 0 1 0];

end_idx = find(diff(conv(~x, ones(1,n))==n)==-1)
start_idx = find(diff(conv(~x, ones(1,n))==n)==1) - n + 2

返回

end_idx =

    6   14   25

start_idx =

    1    9   20

请注意,这部分是两行共有的:diff(conv(~x, ones(1,n))==n),因此将其拉出会更有效:

kernel = ones(1,n);
convolved = diff(conv(~x, kernel)==n);
end_idx = find(convolved==-1)
start_idx = find(convolved==1) - n + 2

【讨论】:

  • 为什么2 不是适合掩码的索引? OP 希望每次出现 5 个连续的零,并且一开始就有 6 个。那么[2 6] 不应该也适合吗?
  • @Adriaan 我不明白 OP 的要求。 “我想找到连续超过 5 个零的所有区域。我想找到它开始和停止的索引。” 听起来像八个 0s in一行只是一个区域,只需要开始和停止。这里可能出错的一件事是,我发现有五个或更多 0s 的区域,而不是严格超过五个的区域,但只需将 n 更改为 6 即可解决此问题。
  • 哦,我完全错过了那部分,我以为他只是想要面具。是的,在那种情况下,你的答案是肯定的;我什至不会尝试扩展我的答案。
【解决方案2】:

你可以这样使用regexp

  • 将数组转换为字符串
  • 删除空白
  • 使用正则表达式查找0的序列

一个可能的实现可能是:

x=[ 1 1 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1]
% Convert the array to string and remove the blanks
str=strrep(num2str(x),' ','')

% Find the occurrences
[start_idx,end_idx]=regexp(str,'0{6,}')

这给出了:

start_idx =  12
end_idx =  17

其中x(start_idx) 是序列的第一个元素,x(end_idx) 是最后一个元素

应用于更长的序列,start_idxend_idx 结果为数组:

x=[0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 1 0 1 0]

start_idx =

    1    9   20

end_idx =

    6   14   25

【讨论】:

  • 将 MATLAB 擅长的模式(数字)中的数组转换为较慢的模式(字符串)听起来不是特别快的方法。
猜你喜欢
  • 2015-05-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多