Any efficient way to identify a set of 1s in a big array?

조회 수: 1 (최근 30일)
Jaya
Jaya 2021년 9월 3일
편집: Stephen23 2021년 12월 6일
I have an array called link_slots of 800 elements made of 1, 0 and -1.
E.g. 1 1 1 -1 0 0 0 0 1 1 -1 0 0 1 1 1 1 -1 0 0 .... So, 1 denotes occupied, 0 for unoccupied and -1 just to mark the end of a set of 1s.
I want to know the start and end indices of each set of 1s. E.g.,here, start as [1,9,14] and end as [3,10,17]. My code works but found out through Profiler that it takes a lot of time. Is there any efficient way to solve this? Considering that I have to do this thing for multiple arrays for size 800 elements.
i=1;
while(i<numel(link_slots(1,:)) ) %to cycle through whole array
j=i
if(link_slots(1,i)==1) %i.e. if occupied
startt(i)=i %store it in the start array
j=i
while(link_slots(index,j+1)~=-1)
j=j+1
end
endd(i)=j %store the end index upon encountering -1
end
i=j+1
end

채택된 답변

Stephen23
Stephen23 2021년 12월 4일
편집: Stephen23 2021년 12월 6일
A simple, efficient, robust solution:
a = [1,1,1,-1,0,0,0,0,1,1,-1,0,0,1,1,1,1,-1,0,0];
d = diff([false,a==1,false]);
s = find(d>0) % start
s = 1×3
1 9 14
e = find(d<0)-1 % end
e = 1×3
3 10 17
And tested on your new data set:
a = [1,1,-1,1,1,1,-1,0,0];
d = diff([false,a==1,false]);
s = find(d>0) % start
s = 1×2
1 4
e = find(d<0)-1 % end
e = 1×2
2 6
  댓글 수: 1
Jaya
Jaya 2021년 12월 4일
편집: Jaya 2021년 12월 4일
Thank you so much. I want to accept your answer as well. Thinking that my comments on a old question won't be visible to wider audience, I asked a fresh question linking to this question here. You may please paste your answer there so that I can accept it there.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Ive J
Ive J 2021년 9월 3일
Try this
a = [1 1 1 -1 0 0 0 0 1 1 -1 0 0 1 1 1 1 -1 0 0];
astart = [1, 9, 14];
astop = [3, 10, 17];
dda = diff([0, 0, diff(a)]);
start = find(dda == 1);
if a(1) > 0
start = [1, start];
end
stop = find(circshift(a < 0, -1));
all(astart == start)
ans = logical
1
all(astop == stop)
ans = logical
1
  댓글 수: 2
Jaya
Jaya 2021년 9월 4일
This really helped to speed up the implementation. Thanks.
Jaya
Jaya 2021년 12월 4일
편집: Jaya 2021년 12월 4일
@Ive J Hello, I am the same person who asked the original question. Your solution worked perfectly. But now I find that when my array is like below then it isn't able to identify the start properly. But stop is ok.
a=[1 1 -1 1 1 1 -1 0 0];
%start is only coming as -1 It should instead come as [1 4]
%stop is working fine. I.e. [2 6]
The difference w.r.t the original question array and this array is only that now, the set of 1s are next to another set of 1s separated by the marker, -1. Whereas in the original question, there were some 0's in between. Can you please help me on this?

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by