对于那里的matlab大师来说这是半个问题和半个挑战:我想让一个函数接受逻辑数组(false/true)并给出包含trues的所有连续区域的开头和结尾struct数组.
像这样的东西:
b = getBounds([1 0 0 1 1 1 0 0 0 1 1 0 0])
Run Code Online (Sandbox Code Playgroud)
应该回来
b = 3x1 struct array with fields:
beg
end
Run Code Online (Sandbox Code Playgroud)
和
>> b(2)
ans =
beg: 4
end: 6
Run Code Online (Sandbox Code Playgroud)
我已经有了一个实现,但我真的不知道如何处理struct数组,所以我想问你怎么做 - 我必须通过mat2cell处理,当我必须处理更大的struct时数组变得很麻烦.我看起来像这样:
df = diff([0 foo 0]);
a = find(df==1); l = numel(a);
a = mat2cell(a',ones(1,l))
[s(1:l).beg] = deal(a{:});
b = (find(df==-1)-1);
b = mat2cell(b',ones(1,l))
[s(1:l).end] = deal(b{:});
Run Code Online (Sandbox Code Playgroud)
小智 7
我不明白你为什么要使用mat2cell等.你犯的问题太多了.
给定布尔行向量V,找到序列中所有1组的起点和终点.
V = [1 0 0 1 1 1 0 0 0 1 1 0 0];
Run Code Online (Sandbox Code Playgroud)
你可以从差异中获得大部分.从而
D = diff(V);
b.beg = 1 + find(D == 1);
Run Code Online (Sandbox Code Playgroud)
这将定位所有组的开始点,除了可能是第一组.所以添加一个简单的测试.
if V(1)
b.beg = [1,b.beg];
end
Run Code Online (Sandbox Code Playgroud)
同样,每组都必须在另一组开始之前结束.所以只需找到终点,再次担心最后一组是否会被遗漏.
b.end = find(D == -1);
if V(end)
b.end(end+1) = numel(V);
end
Run Code Online (Sandbox Code Playgroud)
结果如我们所料.
b
b =
beg: [1 4 10]
end: [1 6 11]
Run Code Online (Sandbox Code Playgroud)
事实上,我们可以更轻松地完成所有这些工作.一个简单的解决方案是在我们执行diff之前始终将零附加到V的开头和结尾.看看它是如何工作的.
D = diff([0,V,0]);
b.beg = find(D == 1);
b.end = find(D == -1) - 1;
Run Code Online (Sandbox Code Playgroud)
同样,结果如预期.
b
b =
beg: [1 4 10]
end: [1 6 11]
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我可能会避免在这里使用end,即使是作为结构字段名称.使用matlab关键字作为变量名称进入是一个坏习惯,即使它们只是字段名称.