我有一个1乘1000(1行乘1000列(的矩阵,它只包含0和1作为元素。我怎么能找到1连续重复3次的次数。
如果有3个以上,则有必要重置计数。因此,4将是3+1,并且它仅计数为3个连续1的一个实例,但6将是3+3,因此它计数为具有3个连续的1的两个实例。
这种方法可以找到A从0到1(上升沿(和从1到0(下降沿(之间的差异。这给出了每个块中连续1的长度。然后将这些数字除以3,四舍五入得到3的运行次数。
在A
的开始和结束处用0填充正好确保如果a以1开始,我们在开始处有上升沿,如果a以0结束,我们在结束处有下降沿。
A = round(rand(1,1000));
% padding with a 0 at the start and end will make this simpler
B = [0,A,0];
rising_edges = ~B(1:end-1) & B(2:end);
falling_edges = B(1:end-1) & ~B(2:end);
lengths_of_ones = find(falling_edges) - find(rising_edges);
N = sum(floor(lengths_of_ones / 3));
或者在可读性差得多的2行中:
A = round(rand(1,1000));
B = [0,A,0];
N = sum(floor((find(B(1:end-1) & ~B(2:end)) - find(~B(1:end-1) & B(2:end))) / 3));
您可以定义您的自定义函数,如下
v = randi([0,1],1,1000);
% get runs in cell array
function C = runs(v)
C{1} = v(1);
for k = 2:length(v)
if v(k) == C{end}(end)
C{end} = [C{end},v(k)];
else
C{end+1} = v(k);
end
end
end
% count times of 3 consecutive 1s
function y = count(x)
if all(x)
y = floor(length(x)/3);
else
y = 0;
end
end
sum(cellfun(@count,runs(v)))
这里有另一种矢量化方式:
% input
n = 3;
a = [1 1 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1]
% x x x x x = 5
% output
a0 = [a 0];
b = cumsum( a0 ) % cumsum
c = diff( [0 b( ~( diff(a0) + 1 ) ) ] ) % number of ones within group
countsOf3 = sum( floor( c/n ) ) % groups of 3
你喜欢脏乱的吗?这里有一条线:
countsOf3 = sum(floor(diff([0 getfield(cumsum([a 0]),{~(diff([a 0])+1)})])/n))