Matlab独特的细胞组合

时间:2017-11-14 15:20:08

标签: matlab list cell

我有一个列表如下:

A= {[1 2], [2 1], [2 1 3],[3 4],[4 3]}

我需要简化矩阵。例如,[3 4][4 3]形成相同的组合,其中只有一个就足够了。此外,[1 2][2 1]是相同的组合,因此我应该留下

newA= {[1 2],[2 1 3],[3 4]}

我该怎么做?

3 个答案:

答案 0 :(得分:5)

最有效的方法可能是对每个向量进行排序并使用两个嵌套循环,如下所示:

As = cellfun(@sort, A, 'UniformOutput', false); % sort each vector
remove = false(size(A)); % initiallize. Entries to be removed will be marked true
for ii = 1:numel(A)
    for jj = ii+1:numel(A)
        remove(jj) = remove(jj) || isequal(As{jj}, A{ii}); % short-circuit OR
    end
end
result = A(~remove);

答案 1 :(得分:5)

一种方法是sort值并使用unique

A = {[1 2], [2 1], [2 1 3],[3 4],[4 3]};

tmp = cellfun(@sort, A, 'UniformOutput', false);
tmp = cellfun(@num2str, tmp, 'UniformOutput', false);
[~, idx] = unique(tmp);

newA = A(idx);

注1:由于A处理单元格数组,我必须制作一个等同于unique的字符串的虚拟数组。 unique只能处理字符串/字符向量的单元格数组,因此我们必须进行一些操作才能获得所需的输出。

注2:cellfun几乎总是比显式循环慢,但我在这里使用它是为了简洁。

答案 2 :(得分:3)

以下是使用accumarray的解决方案:

n = cellfun(@numel,A);
C=accumarray(n(:),1:numel(A),[],@(x){num2cell(unique(sort(vertcat(A{x}),2),'rows'),2)});
result = vertcat(C{~cellfun(@isempty,C)})

我在Octave中使用以下数据测试了3个建议的答案:

A=arrayfun(@(x){randi([1 10],1,randi([1 10000]))},1:50);

结果如下:

======NUM2STR=======:
Elapsed time is 1.13129 seconds.
======FOR LOOP=======:
Elapsed time is 0.237398 seconds.
======ACCUMARRAY=======:
Elapsed time is 0.036804 seconds.

使用以下数据:

A=arrayfun(@(x){randi([1 3],1,randi([1 5]))},1:500);    

结果:

======NUM2STR=======:
Elapsed time is 0.384026 seconds.
======FOR LOOP=======:
Elapsed time is 10.9931 seconds.
======ACCUMARRAY=======:
Elapsed time is 0.0271118 seconds.

Online Demo