2013-06-12 4 views
2

strCellArr을 4000 * 1 셀 배열로 지정하십시오. 각 셀은 문자열입니다.matlab에서 셀 비교

:

내가

a= true; 
For (i =0; i =length(strCellArr); i++) 
    if length(strCellArr{i}) ~= 100 
     a = false; 
    end 
end 

이와 관련된 질문과 같은 일을 뭔가를 원하는 모든 셀 즉 길이 100

의 문자열이 있는지 알 수있는 가장 빠른 방법은 무엇입니까

난과 문자의 4000 * 100 배열로 배열을 변환 할 수 있습니다

charArr = char(strCellArr); 

그러나 이것은 100 문자가없는 행에 공백을 도입합니다. 따라서 34 행의 문자 수는 30 자로 제한됩니다. 그런 다음

charArr(34)(50) 

은 공백을 반환합니다.

내 경우 (A, T, C 또는 G)의 모든 문자가 특정 문자 만 사용하는지 확인하려면 어떻게해야합니까? for 루프를 사용하지 않고이를 수행 할 수있는 방법이 있습니까?

답변

6

가 우 난 그냥 질문을 사랑하는 일 같은 예술 "무엇을 ... 할 수있는 가장 빠른 방법이다"

는 여기에 몇 가지 대안을, 그리고 비교 :

% Initalize 

map = 'CATG';  
strCellArr = cellfun(@(x) map(randi(4,100,1)),cell(4000,1), 'UniformOutput', false); 


% Your original method 
tic 
a = true; 
for el = strCellArr 
    if length(el{1}) ~= 100 
     a = false; 
     break; 
    end 
end 
toc 

% My solution 
tic 
a = all(cellfun('length', strCellArr) == 100); 
toc 

% Dang Khoa's method 
tic 
a = all(cellfun(@(x) length(x) == 100, strCellArr)); 
toc 

% Engineero's method 
tic 
a = all(cellfun(@length, strCellArr) == 100); 
toc 

결과 :

Elapsed time is 0.001158 seconds. % loop 
Elapsed time is 0.000455 seconds. % cellfun; string argument 
Elapsed time is 0.031897 seconds. % cellfun; anonymous function 
Elapsed time is 0.006994 seconds. % cellfun; function handle 

리틀 알려진 사실 : 문자열 입력이 cellfuncellfun 바이너리에 직접 작성된 함수를 의미하므로 익명의 함수를 평가하지 않아도됩니다.즉, cellfun는 제작, 그 반복의 모든에 MATLAB 인터프리터를 통해 패스를 만들 필요가 없습니다이 성난 빠른 :) 이제

, 질문의 두 번째 부분 :

% Engineero 
tic 
A = 'ATCG'; 
all(all(ismember(char(strCellArr), A))); 
toc 

% My solution 
tic 
C = char(strCellArr); 
~any(C(:)==' '); 
toc 

결과 : ismember는 MATLAB m의 코드로 구현되고, (에러 검사, 오류 WA 사용자 편의를위한 코드 투성이 때문에

Elapsed time is 0.061168 seconds. % ismember 
Elapsed time is 0.005098 seconds. % direct comparison to whitespace 

차이가 생긴다 등), 정교한 일반화, 루프 구조 및 기타 모든 것들이 모두 성능 저하의 원인이됩니다. 우리가 공간 char에 캐스팅에 배열에 추가됩니다 것을 사전에 알고 있기 때문에

, 우리는 하지 명시 적으로 'A'의 발생, 'C', 'T', 'G'를 확인해야합니까,하지만 그들의 외계인. 의미, 그냥 그 공백을 찾으십시오 :)

말할 필요도없이,이 시간은 모두 사실상 무시할 만합니다. 그리고 이것은 실제로 정말로 유용한 것보다 더 정신적 인 자위 행위입니다. 그러나 그 재미! :)

+0

내 솔루션에서와 같이'cellfun' 안에'== 100'을 사용하면 외부에 두는 것과 비교하여 런타임이 455 % 증가했습니다. 나는 이것이 왜 있는지 궁금해. 이 경우 분명히 무시할 만하지만 문제를 확대하는 것은 비효율적입니다. 내 솔루션은 프로그래머의 * 장래성, 즉 "설계 의도"가 @ Engineero의 솔루션보다 더 낫다는 생각이 듭니다. 그러나 분명히 그는 스피드에서 승리합니다. 또한, 당신이 나에게 준 학습에 감사드립니다. 문자열 인수! 나는 여전히 디자인 의도가 분명하기 때문에 anon fcns를 사용하는 것을 선호합니다. 그러나 속도가 필요하다면 이것은 좋은 것입니다. –

+3

@DangKhoa : 나는 동의한다. 실제로 MATLAB의 경우가 꽤 자주 있습니다. 설탕으로 코팅 된 것이 많을수록 성능 저하가 더 심해질 것입니다. * 차이점은 MATLAB 인터프리터에서'@ (x)'가 * 평가 *를 강제한다는 사실에 기인합니다. 직접'@ length '는'length' 함수의 * lookup * 만 허용합니다. –

+1

+1 Nitpick :'@ length'는 익명의 함수가 아닙니다. 함수 핸들이고, 아마도 내장 함수 인'length' 함수입니다. 그래서 "짧은 익명의 기능"은 다소 잘못된 이름입니다. 즉, anons은 조금 느립니다 (적어도 과거에는). 그러나 더 긴 익명의 함수는 추가 함수 호출 ('=='과''length()'의 맨 위에있는 anon 호출 자체)과'100'과 임시 변수 생성을 통해 더 많은 (비싼) 작업을 수행하고 있습니다. –

3

첫 번째 질문의 경우 all(cellfun(@length, strCellArr) == 100)을 사용할 수 있습니다. 셀의 모든 요소의 길이가 100 개이면 "true"로 1을 반환합니다.

두 번째 질문의 경우 all(ismember(charArr, A))A = ['A', 'T', 'C', 'G']으로 사용할 수 있습니다. 자세한 내용은 allismember에 대한 설명서를 참조하십시오.

3

첫 번째 질문은 cellfun의 경우와 같습니다. cellfun을 사용하면 셀 배열의 각 셀에서 작업 할 수 있습니다. (제쳐두고, arrayfun을 사용하면 동일한 배열을 사용하지만 동일한 배열을 만들 수 있습니다.) (원래 코드, 특히 for 루프 MATLAB 구문 아닙니다.)

그래서 당신이 여기

res = cellfun(@(x) length(x) == 100, strCellArr); 

처럼 뭔가를 할 수는 == 조건이 0 또는로 평가하기 때문에 reslogical 될 것입니다 결과 all 인 경우 1. 그런 다음 1, 즉, strCellArr 모든 문자열의 길이가 100의 수 있습니다 볼 수 있습니다

a = all(res); 
if a == 0 
    disp('One or more strings does not have 100 characters!'); 
else 
    disp('All strings have 100 characters!'); 
end 
관련 문제