基于重复字符位置创建数组的最简单方法

时间:2012-08-22 16:28:26

标签: arrays matlab

我想使用数组中重复的段对元素进行分组。中断主要取决于重复段的位置,在我的实际数据中包含~10000个元素,我想知道是否有更简单的方法。

这是一个简短的例子来澄清我想要的东西:

假设我有一个数组,

A=[1 5 3 4 4 4 6 9 8 8 9 5 2];

我想要的是将A分解为[1 5 3],[6 9], and [9 5 2];

使用matlab编写最简单的代码是什么?

感谢。

2 个答案:

答案 0 :(得分:3)

对于矢量化解决方案,您可以找出与邻居的前向或后向差异为零的位置,然后使用bwlabel(来自图像处理工具箱)和accumarray来收集数据

A=[1 5 3 4 4 4 6 9 8 8 9 5 2];

d = diff(A)==0;
%# combine forward and backward difference
%# and invert to identify non-repeating elments
goodIdx = ~([d,false]|[false,d]);

%# create list of group labels using bwlabel
groupIdx = bwlabel(goodIdx);

%# distribute the data into cell arrays
%# note that the first to inputs should be n-by-1
B = accumarray(groupIdx(goodIdx)',A(goodIdx)',[],@(x){x})

编辑

如果您希望重复元素也出现在单元格数组中,请使用以下代码替换最后两行代码

 groupIdx = cumsum([1,abs(diff(goodIdx))]);
 B = accumarray(groupIdx',A',[],@(x){x})

<强> EDIT2

如果您希望能够分割连续的相同数字组,则需要按如下方式计算groupIdx

 groupIdx = cumsum([1,abs(diff(goodIdx))|~d.*~goodIdx(2:end)])

答案 1 :(得分:1)

如果我正确理解了问题,这是一个有效的解决方案。它可能会进一步优化。

A=[1 5 3 4 4 4 6 9 8 8 9 5 2];

% //First get logical array of non consecutive numbers
x = [1 (diff(A)~=0)];
for nn=1:numel(A)
    if ~x(nn)
        if x(nn-1)            
            x(nn-1)=0;
        end
    end
end


% //Make a cell array using the logical array
y = 1+[0 cumsum(diff(find(x))~=1)];
x(x~=0) = y;
for kk = unique(y)
    B{kk} = A(x==kk);
end

B{:}