好吧,对此的最佳答案需要了解如何填充 A。如果 A 是稀疏的,也就是说,如果它的列值很少而 B 很大,那么我认为节省内存的最佳方法可能是使用稀疏矩阵而不是单元格。
% No fancy stuff, just fast and furious
bMax = numel(B);
nRows = size(A,1);
cLogical = sparse(nRows,bMax);
for curRow = 1:nRows
curIdx = A(curRow,:);
cLogical(curRow,curIdx) = 1;
end
回答:
cLogical =
(2,1) 1
(3,1) 1
(4,1) 1
(4,2) 1
(1,3) 1
(2,3) 1
(3,3) 1
(1,4) 1
(3,4) 1
(4,4) 1
(1,5) 1
(2,5) 1
如何阅读答案。对于每一列,行显示列索引出现在 A 中的索引。即1
出现在行中[2 3 4]
,2
出现在行中[4]
,3
行中[1 2 3]
,4
行中[1 3 4]
,5
行中[1 2]
。
然后,您cLogical
将来可以根据需要使用代替单元格作为索引矩阵。
另一种方法是为 C 分配索引应在 C 中出现多少次的预期值。
% Fancier solution using some assumed knowledge of A
bMax = numel(B);
nRows = size(A,1);
nColumns = size(A,2);
% Pre-allocating with the expected value, an attempt to reduce re-allocations.
% tic; for rep=1:10000; C = mat2cell(zeros(bMax,nColumns),ones(1,bMax),nColumns); end; toc
% Elapsed time is 1.364558 seconds.
% tic; for rep=1:10000; C = repmat({zeros(1,nColumns)},bMax,1); end; toc
% Elapsed time is 0.606266 seconds.
% So we keep the not fancy repmat solution
C = repmat({zeros(1,nColumns)},bMax,1);
for curRow = 1:nRows
curIdxMsk = A(curRow,:);
for curCol = 1:nColumns
curIdx = curIdxMsk(curCol);
fillIdx = ~C{curIdx};
if any(fillIdx)
fillIdx = find(fillIdx,1);
else
fillIdx = numel(fillIdx)+1;
end
C{curIdx}(fillIdx) = curRow;
end
end
% Squeeze empty indexes:
for curRow = 1:bMax
C{curRow}(~C{curRow}) = [];
end
回答:
>> C{:}
ans =
2 3 4
ans =
4
ans =
1 2 3
ans =
1 3 4
ans =
1 2
哪种解决方案性能最好?您在代码中进行性能测试,因为它取决于 A、bMax 的大小、计算机的内存大小等等。然而,我仍然对其他人可以为这个 x) 做的解决方案感到好奇。我喜欢 chappjc 的解决方案,尽管它有他指出的缺点。
对于给定的示例(10k 次):
Solution 1: Elapsed time is 0.516647 seconds.
Solution 2: Elapsed time is 4.201409 seconds (seems that solution 2 is a bad idea hahaha, but since it was created to the specific issue of A having many rows it has to be tested in those conditions).
chappjc' solution: Elapsed time is 2.405341 seconds.