2014-10-07 3 views
1

벡터를 가져 와서 섹션으로 분할하려고합니다. 이 코드는 다음과 같이 오름차순이 중지 될 때 별도의 벡터를 만들도록 요구합니다. [3, 5, 9, 21, 27, 15, 10, 13][3 5 9 21 27], [15][10, 13]의 세 블록으로 나뉩니다.각 블록이 가장 긴 오름차순 (증가) 시퀀스 인 블록으로 배열을 나눕니다.

저는 루프를 사용하지 않아서 누군가가 나를 도울 수 있다면 도움이 될 것입니다. 감사.

+0

welcome to stackoverflow! 문제가 해결되었음을 시스템에 알리기 위해 (귀하의 질문에 가장 잘 답한 답변)을 수락하는 것을 고려해보십시오 (왼쪽의 녹색 확인 표시). – thewaywewalk

답변

0

diff 함수는 배열의 인접 요소 간의 차이를 계산합니다. diff 결과에서 음수 인 요소는 오름차순이 "손상됨"을 가리 킵니다.

그래서 :

v = [3, 5, 9, 21, 27, 15, 10, 13]; 
dv = diff(v); 
nb = sum(dv <= 0); % number of blocks 
b = cell(1, nb); % container of blocks 

ix = find(dv <= 0); % start indices of blocks 
ix0 = 1; 
for k = 1:nb 
     ix1 = ix(k); 
     b{k} = a(ix0:ix1); 
     ix0 = ix1 +1 ; 
end; 

내 의견은 루프를 사용하여 피하기는하지만, 위의 코드 블록 요소를 찾는 무력 방법에 비해 계산량에 대한 훨씬 더 "부드러운"입니다 어려운 것입니다 요소별로.

2

없음 루프, 한 줄, 나는 그것이 괜찮아 희망)

a = [3, 5, 9, 21, 27, 15, 10, 13]; 

output = accumarray(cumsum([0; diff(a(:))] < 0)+1, a, [], @(x) {x}) 

몇 가지 설명하지 :

%// find out where the vector decreases: 
da = [0; diff(a(:))] 
%// and create a mask 
mask = da < 0 
%// sum the mask up cumulatively and add +1 
subs = cumsum(mask) + 1 
%// use accumarray to gather everything 
output = accumarray(subs,a,[],@(x) {x}) 

같은 수의, 여기처럼 다음이 있다면 :

a = [3, 5, 9, 21, 27, 27, 15, 10, 13]; 

위의 솔루션은 seco를 계산합니다 차 첫 번째 그룹에 27은, 당신이 원하는 경우는 별도의 그룹이 될에 마스크를 변경하려면 다음

mask = da <= 0 
+0

+1 좋은 해결책입니다. –

+1

+1 나부터. 나는 항상 '축적 배열 (accumarray)'해법을 선호한다. – rayryeng

+0

그레이트 해법! –

1

그것은 mat2cell 매우 쉽게 수행 할 수 있습니다

x = find(diff(a)<0); 
result = mat2cell(a, 1, [x(1) diff(x) numel(a)-x(end)]); 

당신이 하나를 원하는 경우 -liner :

result = mat2cell(a, 1, diff(find(diff([inf a -inf])<0))); 
+0

동일한 일이 내가 너무 이것을 실행하면 발생합니다 [4x1 double] [15] [2x1 double] – electricsurge31

+0

+1! 그리고 그 코멘트는 나에게 조금 킥킥 웃자. – thewaywewalk

관련 문제