将数组划分为块,其中每个块是最长的递增(递增)序列

时间:2014-10-07 18:49:15

标签: arrays matlab

我试图将矢量分成几部分。当升序停止时,代码要求我创建一个单独的向量:[3, 5, 9, 21, 27, 15, 10, 13]将分为三个块[3 5 9 21 27][15][10, 13]

我不应该使用循环,所以如果有人能够帮助我,将会有所帮助。感谢。

3 个答案:

答案 0 :(得分:2)

没有循环,一行,我希望它没问题;)

a = [3, 5, 9, 21, 27, 15, 10, 13];

output = accumarray( cumsum([0; diff(a(:))] < 0)+1, a, [], @(x) {x} )

一些解释:

%// find out where the vector decreases:
da = [0; diff(a(:))]
%// and create a mask
mask = da < 0
%// sum the mask up cumulatively and add +1
subs = cumsum(mask) + 1
%// use accumarray to gather everything
output = accumarray(subs,a,[],@(x) {x})

如果后面有相同的号码,就像这里:

a = [3, 5, 9, 21, 27, 27, 15, 10, 13];

上面的解决方案将第二个27计算到第一个组,如果您希望它是一个单独的组,请将掩码更改为:

mask = da <= 0

答案 1 :(得分:1)

使用mat2cell

可以轻松完成
x = find(diff(a)<0);
result = mat2cell(a, 1, [x(1) diff(x) numel(a)-x(end)]);

如果你想要一个单行:

result = mat2cell(a, 1, diff(find(diff([inf a -inf])<0)));

答案 2 :(得分:0)

diff函数计算数组的相邻元素之间的差异。 diff结果中为负数的元素指向升序顺序为“#34;断开&#34;。

所以:

 v  = [3, 5, 9, 21, 27, 15, 10, 13];
 dv = diff(v);
 nb = sum(dv <= 0);  % number of blocks
 b  = cell(1, nb);   % container of blocks

 ix  = find(dv <= 0);  % start indices of blocks
 ix0 = 1;
 for k = 1:nb
         ix1 = ix(k);
         b{k} = a(ix0:ix1);
         ix0 = ix1 +1 ;
 end;

我的观点是很难避免使用循环,但是,上面的代码更加温和&#34;关于计算负荷与逐元素逐块找到的强力方法相比较。