1 view (last 30 days)

Hi

I have a column vector of 1s and 0s and I want to find find the number of rows to the next row containing a 1. For example:

A = [0 0 0 1 0 1 1 1 0 0 0 0 0 1]';

I would like the code to return

B = [3 2 1 0 1 0 0 0 5 4 3 2 1 0]';

Is there a vectorized way that this can be done?

Thanks in advance

Rik
on 27 Aug 2020

Edited: Rik
on 27 Aug 2020

It took some time, but here is a solution that should also work for large matrices.

clc,clear

format compact

A = [0 0 0 1 0 1 1 1 0 0 0 0 0 1]';

% 3 2 1 0 1 0 0 0 5 4 3 2 1 0

B=A;

pad=B(end)~=1;

if pad,B(end+1)=1;end %this method requires the last position to be a 1

B=flipud(B);

C=zeros(size(B));

C(B==1)=[0;diff(find(B))];

C=ones(size(B))-C;

out=cumsum(C)-1;

out=flipud(out);

if pad,out(end)=[];end

%only for display:

[A out]

Bruno Luong
on 27 Aug 2020

When I run this code with

A = [0;0;0]

I get

out=[3;2;1]

Does it meet the description "find the number of rows to the next row containing a 1".

To me no since there is no 1 in A it should return [0;0;0].

My code also have this flaw.

Rik
on 27 Aug 2020

Binbin Qi
on 27 Aug 2020

A = [0 0 0 1 0 1 1 1 0 0 0 0 0 1]';

C = find(A);

D = (1:length(A)) - C;

D(D>0) = D(D>0) + inf';

min(abs(D))'

ans =

3

2

1

0

1

0

0

0

5

4

3

2

1

0

Binbin Qi
on 27 Aug 2020

if data is larger, you can use the code following

A = [0 0 0 1 0 1 1 1 0 0 0 0 0 1]';

A = [A;1]; %

B = cell2mat(cellfun(@(x)(length(x)-1:-1:0)',...

mat2cell(A, diff([0;find(A==1)])),...

'UniformOutput',false));

B(end) = []

Bruno Luong
on 27 Aug 2020

Edited: Bruno Luong
on 27 Aug 2020

As much as I love vectorization, this problem is a typical case where the for-loop method is easier, faster, more readable.

This code is ready for 2D array, it works along the first dimension independently.

A=rand(30000,1000)>0.7;

tic

Al=logical(A);

B=zeros(size(A));

b=B(1,:);

for k=size(B,1):-1:1

b = b+1;

b(Al(k,:))=0;

B(k,:)=b;

end

toc

Bruno Luong
on 28 Aug 2020

Edited: Bruno Luong
on 28 Aug 2020

Now I just discover CUMSUM has direction option, this is based on Rik's cumsum method, but avoid the double flipping.

B = ones(size(A));

i1 = find(A);

B(i1) = 1-diff([i1;size(A,1)+1]);

B = cumsum(B,'reverse');

Rik
on 28 Aug 2020

Opportunities for recent engineering grads.

Apply TodayFind the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
## 10 Comments

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987248

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987248

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987275

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987275

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987452

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987452

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987821

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987821

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987878

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_987878

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988043

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988043

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988088

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988088

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988367

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988367

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988409

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988409

## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988463

⋮## Direct link to this comment

https://la.mathworks.com/matlabcentral/answers/585170-finding-the-number-of-rows-to-the-next-row-containing-a-1#comment_988463

Sign in to comment.