Count the occurence of a number in between other numbers
4 ビュー (過去 30 日間)
古いコメントを表示
I need to extract the number of zeros of the vector highlighted below.
x = [ 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0]
My expected outcome is,
y = [2 1 5 1 1]
I need to get the number of 0s in between the 1s. I tried several "for" and "while" loops. But wasnt able to get this result.
Appreciate if anyone can help me out.
0 件のコメント
採用された回答
Stephen23
2019 年 2 月 22 日
編集済み: Stephen23
2019 年 2 月 22 日
This is simpler and actually works for all horizontal vectors (unlike the accepted answer):
>> x = [ 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0];
>> D = diff([false,x==0,false]);
>> find(D<0)-find(D>0)
ans =
2 1 5 1 1
For a slightly faster version you can call find once:
>> F = find(diff([false,x==0,false]));
>> F(2:2:end)-F(1:2:end)
ans =
2 1 5 1 1
EDIT: uses Jan's logical vector suggestion.
5 件のコメント
Stephen23
2019 年 2 月 22 日
"...like I stated those cases would be satisfied with one simple if condition ."
Please show how that would work.
その他の回答 (4 件)
Jan
2019 年 2 月 21 日
Another solution:
x = [ 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0];
y = [1, x, 1];
strfind(y, [0,1]) - strfind(y, [1,0])
Jan
2019 年 2 月 12 日
編集済み: Jan
2019 年 2 月 12 日
[B, N] = RunLength(x);
Result = N(B == 0)
If you do not have a C-compiler installed, use RunLength_M from the same submission.
Without RunLength:
x = [ 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0]
d = [true, diff(x) ~= 0]; % TRUE if values change
b = x(d); % Elements without repetitions
n = diff(find([d, true])); % Number of repetitions
Result = n(b == 0)
madhan ravi
2019 年 2 月 12 日
編集済み: madhan ravi
2019 年 2 月 12 日
index=find(x==0); % edited after Jan’s comment
idx=find(diff(index)~=1);
R=[idx(1) diff(idx) numel(index)-idx(end)]
13 件のコメント
Stephen23
2019 年 2 月 22 日
編集済み: Stephen23
2019 年 2 月 22 日
"Just a simple if condition would satisfy those needs."
There are several problems with that approach:
- How do you know that your IF covers all of the special cases? Can you prove that you have thought of every special case?
- Extra complexity makes code harder to understand and maintain, and is more libale to bugs.
- It just shifts the problem: okay, so you can detect a special case, but then how do you deal with it? Solution: by writing code that handles that special case... in which case, you still have to solve the same problem.
- It really would not be that simple. Make a list of the cases for which your code fails: how would you deal with them using one IF statement?
Jan
2019 年 2 月 22 日
編集済み: Jan
2019 年 2 月 22 日
D = diff(find(diff([false, x==0, false])));
R = D(1:2:end);
A short test (yes, I know that timeit is more accurate):
A = ones(1, 1e5);
A(randperm(1e5, 5e4)) = 0;
tic % My strfind method
for k = 1:100
D = [false, A==0, false];
R = strfind(D, [true, false]) - strfind(D, [false,true]);
end
toc % 0.182 seconds
tic % My general RunLength code:
for k = 1:100
d = [true, diff(A) ~= 0];
b = A(d);
n = diff(find([d, true]));
Result = n(b == 0);
end
toc % 0.220 seconds
tic % Stephen's 2 FIND
for k = 1:100
D = diff([0, A==0, 0]);
R = find(D<0) - find(D>0);
end
toc % 0.190 seconds
tic % Stephen's 1 FIND (with modification)
for k = 1:100
D = find(diff([false, A==0, false])); % 10% faster than [0, A==0, 0] !
R = D(2:2:end) - D(1:2:end);
end
toc % 0.161 seconds, was 0.172 with [0, A==0, 0]
tic % Jos
for k = 1:100
D = diff(find(diff([false, A==0, false])));
R = D(1:2:end);
end
toc % 0.161 seconds
[false, A==0, false] creates a logical vector, while [0, A==0, 0] is a double vector, which is 8 times larger.
I'm going to create a C-MEX function for this task, which avoids the time consuming explicit creation of [false, A==0, false].
1 件のコメント
Jos (10584)
2019 年 2 月 22 日
Nice, Jan!
I think this shows the power of the matlab community: we all can learn from it! :-)
参考
カテゴリ
Help Center および File Exchange で Logical についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!