Reputation: 909
I want to count all lengths of sequences of consecutive integers and return those as a vector.
For example, consider the vector:
x = [1 2 3 4 6 8 9 10 12 13];
The lengths will be:
length([1 2 3 4]) = 4;
length([6]) = 1;
length([8 9 10]) = 3;
length([12 13]) = 2;
So, the result I want to generate is:
y = [4 1 3 2]
How can I achieve this?
Upvotes: 0
Views: 1052
Reputation: 112659
A small variation of A. Donda's answer:
diff
to detect differences larger than 1. This gives a 1
value at the end of each run.cumsum
) to assign a different numeric label to each run. Accumulation is done backwards because the 1
values in step 1 are at the end of each run, not at the beginning.histc
.Code:
y = [diff(x)>1 1]; %// step 1
y = cumsum(fliplr(y)); %// step 2
y = fliplr(histc(y, 1:y(end))); %// step 3
Upvotes: 2
Reputation: 6084
This is equal to the run lengths of x - (1:length(x))
. Therefore you could use:
runLengths = @(x) diff([0, reshape(find(x(1:end-1)~=x(2:end)),1,[]), numel(x)]);
sequenceCounts = @(x) runLengths(x(:)-(1:numel(x)).');
result = sequenceCounts(x);
Upvotes: 1
Reputation: 8467
This should do the trick:
y = diff(find(diff([nan ; x(:) ; nan]) ~= 1))
The inner diff
looks for steps that are not +1 (sequence breaks), the find
determines the corresponding positions (indices), the outer diff
computes sequence lengths as differences between sequence break positions. The nan
s are there to make sure that the sequence at the beginning and the sequence at the end of the vector are found, by inducing diff
values different from 1.
Upvotes: 3
Reputation: 2778
x = [1 2 3 4 6 8 9 10 12 13];
consecs = []; % empty vector to store answers
consec = 1; % initialize
for I=2:length(x)
if x(I)==x(I-1)+1 % this one is consecutive with previous
consec = consec+1;
else % this one starts a new set of consecutives
consecs(end+1) = consec;
consec = 1;
end
end
consecs(end+1)=consec; % remember to include the last consecutives
display(consecs)
This is tested and it works.
Upvotes: 0