给定一个矩阵,找到每行中最后一个非零元素的索引?

11

对于一个任意大小的矩阵x,如何找到给定矩阵中每一行最后一个非零元素的索引?

例如,对于矩阵

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ]

应该获得向量[ 3 6 0 5 ]


1
这不会是作业吧? - LittleBobbyTables - Au Revoir
1
这看起来更像是作业... - FatherStorm
2
是的,它确实如此,但这是一个有趣的问题。 - Jonas
3
我知道我曾经看到过一个类似的问题(将其放在我的收藏夹中):https://dev59.com/x0fRa4cB1Zd3GeqP9Xub - Amro
4个回答

10

这里有一个更短的版本,结合了findaccumarray

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
%# get the row and column indices for x
[rowIdx,colIdx] = find(x);
%# with accumarray take the maximum column index for every row
v = accumarray(rowIdx,colIdx,[],@max)'
v =
     3   6   0   5

1
不错的accumarray用法,我会记住的。+1 - Adrien

4

以下是一种版本:

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
c = arrayfun(@(k) find(x(k,:)~=0,1,'last'), 1:size(x,1), 'UniformOutput',false);
c( cellfun(@isempty,c) ) = {0};
v = cell2mat(c);

v =
     3     6     0     5

编辑: 考虑使用以下替代方案:

[m,v] = max( cumsum(x'~=0) );
v(m==0) = 0;

v =
     3     6     0     5

你可能可以写一个更好的向量化解决方案,使用CUMSUM和DIFF的组合..看看我能不能想出一个 :) - Amro
1
@Jack Lu:如果您发现某个解决方案有用,请考虑给它点赞或接受它。 - Jonas
'~=' 是什么意思?将 x 转置,然后检查每个单元格不等于零的点。 - hhh
@hhh: ~= 是逐元素的不等式运算符。转置只是一个细节,我们可以明确指定要处理的维度:[m,v] = max(cumsum(x~=0,2),[],2)。下一行处理了所有元素都为零的行的情况。 - Amro

2
使用 bsxfun 的一行解决方案:
result = max(bsxfun(@times, x~=0, 1:size(x,2)).');

或者使用max的两个输出:

[val, result] = max(fliplr(x~=0).',[],1); %'
result = (size(A,2)+1-result).*val;

1

我的答案有点扭曲,但也应该能行

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
[~,pos] = max([fliplr(x~=0),ones(size(x,1))],[],2);
v = size(x,2)-pos' +1;

确实,糟糕的剪贴复制,现已修复。 - Adrien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接