2012-01-29 2 views
2

У меня есть вектор, как:Нахождение чередующихся последовательностей в MATLAB

x = [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1] 

Как я могу захватить начальную и конечную индекс чередующейся последовательности? (т. е. 1 и 2)

+0

вы можете посмотреть на 'ABS (диф (x)) ', а для чередующихся последовательностей длины не менее N , это будет прогон как минимум N одинаковых чисел, которые не равны 0. –

+0

hmmm, scrap that - это дополнительно классифицирует '1,3,5,7, ..' как чередующуюся последовательность. –

ответ

1

Я думаю, что это классный метод, хотя методы численного/массива будут быстрее: P Вы можете использовать регулярное выражение!

% convert into a space-separated string 
% (surely there's a better way than converting to cell array first?) 
str = strcat({num2str(x)}) 
% for some reason all elements are separated by more than one space, convert 
% so they're separated by a single space 
str = regexprep(str,' +',' ') 

% find start & end indices (into str) alternating sequences 
[s e]=regexp(str,'\<([^ ]+) ((?!\1)[^ ]+)(?: \1 \2)+(?: \1)?\>'),'start','end') 
% convert these indices into indices into `x` 
% (at the moment s & e include spaces) 
s = (cell2mat(s)+1)/2 
e = (cell2mat(e)+1)/2 

% run i is at x(s(i):e(i)) 
1

Если вы знаете, что есть только одна последовательность, и это всегда [1 2 ... 1 2], вы можете просто использовать strfind

x = [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1]; 

idx = strfind(x, [1 2]); 

start = idx(1); 
end = idx(end)+1; 

Если может быть несколько вхождений, или если это не всегда 1-2, или если последовательность не является полным (например, 1 2 1, вместо 1 2 1 2), вы можете использовать вместо diff:

dx = diff(x); 
alt = dx(2:end)==-dx(1:end-1) & dx(1:end-1)~=0; 

starts = find(diff(alt)>0) + 1; 
ends = find(diff(alt)<0) + 2; 
Смежные вопросы