identifying and isolating consecutive numbers

I have a vector, for example, A= [1 2 3 4 14 15 23 24 25 ]
and I want a code that will identify regions of consecutive numbers and separate them into their own array. ie, a code that will split A into
B = [1 2 3 4] C = [14 15] D = [23 24 25]
I would like this code to be able to work on a matrix A of variable length. Any suggestions?
Thank you!

 Respuesta aceptada

Maziyar
Maziyar el 8 de Oct. de 2015
Editada: Maziyar el 8 de Oct. de 2015
A(end+1) = 2 % Add a new isolating point end
I_1 = find(D ~= 1); % Find indexes of isolating points
[m,n] = size(I_1);
Start_Idx = 1 ; % Set start index
for i = 1:n
End_Idx = I_1(i); % Set end index
Sequ = A(Start_Idx:End_Idx) % Find consecuative sequences
Start_Idx = End_Idx + 1;
% update start index for the next consecuitive sequence
end

4 comentarios

BKa
BKa el 6 de Jun. de 2019
What should "D" be defined as for this last code
Hi, I used this answer in a related problem that I had.
I'm pretty sure "D" is diff(A)
I had to workshop and troubleshoot it a little to match my problem, but it should work for any consecutive number type problem you have, for me its indices. The code is below:
A= [1 2 3 4 14 15 23 24 25 ] % your array of values
A(end+1)=2 % adds new endpoint to very end of A so code picks up end of last group of consecutive values
I_1=find(diff(A)~=1); % finds where sequences of consecutive numbers end
[m,n]=size(I_1); % finds dimensions of I_1 i.e. how many sequences of consecutive numbers you have
startpoint=1; % sets start index at the first value in your array
seq=cell(1,n) % had to preallocate because without, it only saved last iteration of the for loop below
% used n because this array is a row vector
for i=1:n
End_Idx=I_1(i); %set end index
seq{i}=A(startpoint:End_Idx); %finds sequences of consecutive numbers and assigns to cell array
startpoint=End_Idx+1; %update start index for the next consecutive sequence
end
Hope this helps!
Huge thanks to @Maziyar for the code, this really helped me out of sticky spot!!!
Paul Safier
Paul Safier el 10 de Jul. de 2021
Thanks @Teddy Fisher for the extra annotation.
Samantha Plesce
Samantha Plesce el 27 de Oct. de 2021
I was trying to use this snipet for the same application. I have been testing it with various arrays that contain consecutive sequences. I am having an issue with actually finding the correct set of sequences.
When A = ...
A= [2 4 5 7 8 9 10 -3 -2 -1 0 20] % your array of values
The desired seq cell array should contian:
{[4 5], [7 8 9 10], [-3 -2 -1 0]}
While these sets do appear in the seq cell array, it is also accounting for the first and last value even though they are not apart of a sequence of consecutive values.
seq =
1×5 cell array
{[2]} {1×2 double} {1×4 double} {1×4 double} {[20]}

Iniciar sesión para comentar.

Más respuestas (4)

Walter Roberson
Walter Roberson el 14 de Jun. de 2012

3 votos

The splits should occur at places where diff(A) has 1's . (You can find the runs of 1's by looking at diff(diff(A)).
Once you know the length of each piece, you can use mat2cell() to break up the vector into cell arrays. (Writing to individual variables is not a good practice for something like this.)

1 comentario

Diego Tasso
Diego Tasso el 14 de Jun. de 2012
Follow what Mr. Walter Roberson said he is most correct.

Iniciar sesión para comentar.

Diego Tasso
Diego Tasso el 14 de Jun. de 2012

0 votos

Use regexp to do this, something like ( but not exactly):
[B] = regexp(A,'[1-4]','match')
repeat for C and D replacing [1-4] with the number ranges you want to isolate...this might work...not sure.

2 comentarios

Diego Tasso
Diego Tasso el 14 de Jun. de 2012
By the way this is the cheap inefficient way to get this done...I am sure you can create a loop to do so for you.
Guillaume
Guillaume el 8 de Oct. de 2015
regexp is a cheap and efficient way of locating patterns in strings. It does not apply to numbers.
A loop is the most inefficient way of dealing with the problem.

Iniciar sesión para comentar.

Frank Uhlig
Frank Uhlig el 5 de Mayo de 2020
Editada: Frank Uhlig el 5 de Mayo de 2020

0 votos

Here is a simple sequence that gives the adjacent integers without the non-adjacent ones:
Strat with k = [ 1 2 3 4 7 8 9 12 13 140],
>> k = [ 1 2 3 4 7 8 9 12 13 140],
k =
1 2 3 4 7 8 9 12 13 140
>> i = find(diff(k) == 1),
i =
1 2 3 5 6 8
>> all = unique(sort([k(i),k(i)+1]))
all =
1 2 3 4 7 8 9 12 13
And you have all adjacent integer groups united in ascending order.
Sorting the last output into individual adjacent integer groups now is another problem.
Eric
Eric el 2 de Dic. de 2023
Editada: Eric el 2 de Dic. de 2023
I know this is a very late answer but wasn't sure how to implement the answer by Maziyar because it uses a variable 'D' that is not defined anywhere. I ended up writing my own and it turned out well so I thought I'd share it.
A= [1 2 3 4 14 15 23 24 25 ]
assert(size(A,1)==1 && isa(A,'double'));
p=find(diff(A)>1);
ind=[A(1),A(p+1);A(p),A(end)];
% ind =
% 1 14 23
% 4 15 25
It takes in a vector A that would have a series of sequential numbers and returns a matrix where the top rop is the start of each sequence and the bottom row is the end of each sequence.

2 comentarios

Katerina F
Katerina F el 16 de Feb. de 2024
I am getting this error:
Operands to the logical AND (&&) and OR (||) operators must be convertible to
logical scalar values. Use the ANY or ALL functions to reduce operands to logical
scalar values.
Any suggestions please?
Eric Homer
Eric Homer el 16 de Feb. de 2024
What's the data you are passing in. Can you please share what is causing the issue?

Iniciar sesión para comentar.

Categorías

Más información sobre Characters and Strings en Centro de ayuda y File Exchange.

Preguntada:

el 14 de Jun. de 2012

Comentada:

el 16 de Feb. de 2024

Community Treasure Hunt

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

Start Hunting!

Translated by