如何找到一组特定值在数组中出现的次数?
How to find the number of times a group of a specific value is present in an array?
我有一个 1 x 1000(1 行 x 1000 列)矩阵,其中仅包含 0 和 1 作为它们的元素。我怎样才能找到连续重复 3 次 1 的次数。
如果超过3个则需要重新计数。所以 4 是 3+1,它只算作 3 个连续 1 的一个实例,但 6 是 3+3,所以它算作有 3 个连续 1 的两个实例。
此方法找出 A 从 0 到 1(上升沿)和从 1 到 0(下降沿)的区别。这给出了每个块中连续 1 的长度。然后将这些数字除以 3 并向下舍入以获得 3 的运行次数。
在开始和结束处用 0 填充 A
只是确保如果 A 以 1 开头,我们在开始处有一个上升沿,如果 A 以 a 结尾,我们在结尾处有一个下降沿1.
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));
或者在可读性较差的两行中:
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))
我有一个 1 x 1000(1 行 x 1000 列)矩阵,其中仅包含 0 和 1 作为它们的元素。我怎样才能找到连续重复 3 次 1 的次数。
如果超过3个则需要重新计数。所以 4 是 3+1,它只算作 3 个连续 1 的一个实例,但 6 是 3+3,所以它算作有 3 个连续 1 的两个实例。
此方法找出 A 从 0 到 1(上升沿)和从 1 到 0(下降沿)的区别。这给出了每个块中连续 1 的长度。然后将这些数字除以 3 并向下舍入以获得 3 的运行次数。
在开始和结束处用 0 填充 A
只是确保如果 A 以 1 开头,我们在开始处有一个上升沿,如果 A 以 a 结尾,我们在结尾处有一个下降沿1.
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));
或者在可读性较差的两行中:
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))