How do I find no. of instances of each value till it changes?

I have the following input: [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
I want MATLAB to give me the number of 4s and 0s in each set till the digit changes. So I want my output to be: [6 3 6 8 5].
Thank you!

Answers (2)

You can use the runlength function that Jan made.
Another option is using the code below.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
diff([0 find(diff(input)) numel(input)])
This can be achieved nicely with regular expressions. Capture a digit and backreference back to the same digits to find the patterns of consecutive numbers.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
num = regexp(char(input+'0'),'(\d)\1+','match');
n = cellfun(@numel, num)
>>n
6 3 6 8 5

6 Comments

This is quite an expensive function, although this is masked if you don't suppress output. I didn't test Jan's submission, so that might be even faster.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
t1=0;t2=0;
for k=1:10000
tic
n=diff([0 find(diff(input)) numel(input)]);
t1=t1+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+','match');
n=cellfun(@numel, num);
t2=t2+toc;
end
disp(t1)%0.0604 sec
disp(t2)%0.4362 sec
Yes you are right, your solution is a lot faster!
@Rik my solution can actually be improved to:
num = regexp(char(input+'0'),'(\d)\1+');
diff([num numel(input)+1])
Could you run the profiling again? I suspect your solution will still be faster, however I am curious. I know @cellfun can be expensive.
You can run the code yourself as well, but here it is (on another pc now). Your second solution is indeed a bit faster (~25%).
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
t1=0;t2=0;t3=0;
for k=1:10000
tic
n=diff([0 find(diff(input)) numel(input)]);
t1=t1+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+','match');
n=cellfun(@numel, num);
t2=t2+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+');
n=diff([num numel(input)+1]);
t3=t3+toc;
end
disp(t1)%0.0298 sec
disp(t2)%0.2929 sec
disp(t3)%0.2220 sec
Cheers! Your solution is indeed very efficient. Reason as to why I asked you to do it is because I am on mobile and do not have pc access.
It's a not-uncommon question, so I've seen some solutions before. My first instinct with the first I saw was a for-loop, so yours is miles better already.
And yeah, it's a bit much to copy this code to Matlab online or the app, just to have a benchmark, so I fully understand ;)

Sign in to comment.

Categories

Asked:

on 18 Jul 2018

Commented:

Rik
on 18 Jul 2018

Community Treasure Hunt

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

Start Hunting!