2010-10-11 8 views
11

Wie finde ich für eine beliebig große Matrix x den Index des letzten Nicht-Null-Elements in jeder Zeile einer gegebenen Matrix?Suchen Sie den Index des letzten Nicht-Null-Elements in jeder Zeile einer gegebenen Matrix?

beispielsweise für die Matrix

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 ] 

der Vektor [ 3 6 0 5 ] sollte erhalten werden.

+1

Diese wären nicht zufällig Hausaufgaben, oder? – LittleBobbyTables

+1

sieht das für mich eher wie Hausaufgaben aus ... – FatherStorm

+2

Ja, tut es, aber es ist eine lustige Frage. – Jonas

Antwort

4

Hier ist eine Version:

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 

EDIT: Betrachten Sie diese alternative Lösung:

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

v = 
    3  6  0  5 
+0

Sie cab wahrscheinlich eine bessere vektorisierte Lösung mit einer Kombination aus CUMSUM und DIFF schreiben .. Mal sehen, ob ich eine herausfinden kann :) – Amro

+0

Ich schätze wirklich, dass .. –

+1

@Jack Lu: Wenn Sie eine Lösung nützlich finden, denken Sie bitte darüber nach, sie zu übernehmen/zu akzeptieren. – Jonas

10

Hier ist eine kürzere Version, die Kombination von find und accumarray

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

nice accumarray Verwendung, ich werde versuchen, mich daran zu erinnern. +1 – Adrien

1

Meine Antwort ist ein bisschen verdreht, aber es sollte auch mit bsxfun

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; 
+0

müssen Sie eins zu 'v' hinzufügen ... – Amro

+0

wahr, schlecht ausschneiden & einfügen, jetzt behoben. – Adrien

2

One-Line-Lösung arbeiten:

result = max(bsxfun(@times, x~=0, 1:size(x,2)).'); 

Oder nutzen Sie die beiden Ausgänge von max:

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