• 검색 결과가 없습니다.

논리함수와 조건문/반복문

N/A
N/A
Protected

Academic year: 2022

Share "논리함수와 조건문/반복문"

Copied!
12
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

화공전산응용 4 차시

논리함수와 조건문/반복문

논리함수

논리함수는 매틀랩에서 중요한 함수로 여기선 find() 함수를 연습하게 된다. 일반 프로그램(밍) 언어에서 조건문/선택문은 단일 요소/스칼라의 조건만 선택하지만 행렬(Matrics) 기반 매트랩은 벡터/행렬(숫자 묶음)에 대한 조건을 (동시에)처리하는 논리함수를 사용하도록 만들었다.

1. 벡터(열, 행)에서 찾기

예를 들어 A=[1 5 6 3 4 2 7] 일 경우 여기서 ‘5’ 이상인 수를 확인하려면 보통은 반복문과 조건문을 써서 A 행렬의 요소(숫자 하나)를 하나 하나 조사해봐야 한다.

% Logical function - find() A=[1 5 6 3 4 2 7] ;

Over_5=[];

for k=1:length(A) if A(k)>=5

Over_5=[Over_5, k];

end end Over_5 find(A>=5)

>> find_for Over_5 =

2 3 7 ans =

2 3 7

A 행렬에서 5 이상인 수는 A 행렬에서 두번째, 세번째, 일곱번째에 있는 수/요소/값이다.

매틀랩에서 행렬을 처리하는 논리함수, find()를 쓰면 쉽게 숫자 묶음(벡터, 행렬)으로 처리한다.

(2)

키가 66 인치 이상이면 키 조건에서 합격이다.

>> h=[63 67 65 72 69 78 75];

>> pass=find(h>=66) pass =

2 4 5 6 7

그럼 합격생의 평균 키는?

>> mean(h(pass)) ans =

72.2000

합격생 중에서 가장 키 큰 사람은 응시자 중에서 가장 키 큰 사람과 같으니 문제가 되지 않고, 가장 작은 키로 합격한 응시자는?

>> min(h(pass)) ans =

67

67 인치로 합격한 사람이 가장 작은 합격생이다. 그럼 이 사람은 응시생 중에서 몇 번째인가?

min()는 출력인자를 두 개로 만들어야 Index No. 가 나온다.

>> [a,b]=min(h(pass)) a =

67 b = 1

>> pass(b) ans = 2

즉, 두번째 응시생이 가장 작은 키로 합격했다.

(3)

2. 조건이 2 개 이상인 경우

응시생의 나이는 다음과 같다. a=[18 19 18 20 36 34 12];

나이 조건은 18 세 이상 35 세 미만이다. 수학식으로는 18<=age<35 이지만 매트랩을 포함한 프로그래밍 언어에선 age>=18 and age<35 로 두 조건의 합(동시 만족)으로 표시해야 한다.

따라서 키 조건과 나이 조건이 모두 맞아야 하므로 합격생은?

h=[63 67 65 72 69 78 75]; a=[18 19 18 20 36 34 12];

A=[h; a];

pass=find(A(1,:)>66 & A(2,:)>=18 & A(2,:)<35)

pass =

2 4 6

A 행렬에는 행 별로 다른 자료가 들어 있다. 1 행에는 키가 2 행에는 나이가 …

>> A A =

63 67 65 72 69 78 75 18 19 18 20 36 34 12

이런 행 벡터 모음/묶음 자료/행렬은 fprintf()로 출력하면 열 벡터 자료 출력이 된다.

합격생의 응시 번호와 키 그리고 나이를 열 별로 출력시키려 한다. 앞서 만든 pass 변수에선 합격생의 응시 번호가 들어 있다. 이러한 자료는 모두 행 별로 되어 있고 이를 묶어 출력하면 열 별로 출력된다.

>> fprintf('%d 번 응시생은 키가 %d 인치이고 나이는 %d 세로 합격!\n',[pass;A(1,pass);A(2,pass)]) 2 번 응시생은 키가 67 인치이고 나이는 19 세로 합격!

4 번 응시생은 키가 72 인치이고 나이는 20 세로 합격!

6 번 응시생은 키가 78 인치이고 나이는 34 세로 합격!

(4)

다음처럼 B 로 별도 행렬을 만들어 처리해도 좋다.

>> B=[pass;A(1,pass);A(2,pass)]

B =

2 4 6 67 72 78 19 20 34

>> fprintf('%d 번 응시생은 키가 %d 인치이고 나이는 %d 세로 합격!\n',B) 2 번 응시생은 키가 67 인치이고 나이는 19 세로 합격!

4 번 응시생은 키가 72 인치이고 나이는 20 세로 합격!

6 번 응시생은 키가 78 인치이고 나이는 34 세로 합격!

fprintf()에서 열 별로 출력하므로 2, 67, 19, \n(줄 바꾸기) 순으로 출력하게 된다.

3. 논리함수 잘못 쓰는 예

find() 함수는 다른 프로그래밍 언어에서는 없는 것이고 많이 써오든 min(), max() 함수와 비슷하나 사용 방법이 달라 오류가 많이 나온다. 바른 사용법을 위해 오류를 정리하였다.

(1) 첫 번째 실수: find()에 몰두하여 max()를 같이 생각

max()는 최대값을 반환, find()는 조건에 맞는 번호(index)를 반환 max() 함수에서 순번(index)를 가져오려면 출력을 두 개로 해야 한다.

>> A=[33 55 66 48 56 65];

>> [maxn maxi]=max(A) maxn =

66 maxi = 3

>> a=find(A==max(A)) %무조건 인덱스만 찾는다 a =

3

(5)

>>a=max(A) %이러면 인덱스가 아니라 값을 찾는다 a =

66

행렬에서 max()는 열 별 최대값(과 인덱스)를 찾고 find()는 전체에서 인덱스만 찾는다(하나 또는 두 개)

>> B=[A;44 55 88 22 89 67; 55 88 89 67 79 82]

B =

33 55 66 48 56 65 44 55 88 22 89 67 55 88 89 67 79 82

>> [a b]=max(B) % 열 별로 최대값과 인덱스를 찾는다 a =

55 88 89 67 89 82 b =

3 3 3 3 2 3

>> find(B==max(B(:))) %전체 행렬에서 최대값 인덱스를 가져온다

ans = 9 14

>> [a b]=find(B==max(B(:))) %출력인자를 두 개 쓰면 행과 열 값을 가져온다 a =

3 2 b = 3

(2) 두 번째 실수는 행렬에서 열 별로 찾는 문제에서

(6)

몽땅다(‘:’)를 쓰는 문제이다. 열 별로 자료가 정리된 경우 1 열은 A(:,1), 2 열은 A(:,2)로 4 장 ‘행렬 다루기’에서 연습한 내용이다.

>> h=[63 67 65 72 69 78 75];

>> a=[18 19 18 20 36 34 12];

>> ha=[h;a]' ha =

63 18 67 19 65 18 72 20 69 36 78 34 75 12

>> pass=find(ha(:,1)>=66 & ha(:,2)>=18 & ha(:,2)<35) pass =

2 4 6

사실은 아래를 생각하면서 했기에 ‘열 별 비교’가 헷갈리게 되었다. max()등은 열 별로 처리하는데 find()는 전체를 처리하지만 열 별로 비교하면 전체 조건에 맞는 행 번호를 반환한다. 하나로 묶여있는 행렬에선 그렇지만 따로 떨어진 벡터에서 비교하면 어떠나 하는 마음이 있었다. 결과는 같다.

>> pass=find(h>=66 & a>=18 & a<35) pass =

2 4 6

(7)

find() 함수는 인덱스 번호만 가져온다(반환하다. 찾아낸다). 행렬에서 열 별 비교를 하면 행 번호만 가져오고 이 행 번호 간에 논리연산(&, | ~)된 결과가 나온다. 다른 벡터에서 작업해도 같다. 벡터에서 인덱스 번호를 가져오고 이 들간의 논리연산 결과가 출력된다.

지금 생각하니 당연한 것인데 수업 중엔 학생들 앞에서 키보드를 치면서 하다가 잘 되지 않으면 그 순간에 다른 생각들을 하게 되니 더 안되게 된다(몸과 맘은 처음 것을 하고 있는 도중에 머리에선 또 다른 몇 가지 생각을 하며 이 문제를 어떻게 해결할까 하니, 즉 뇌에서 멀티태스킹이 걸리는 데 멀티태스킹은 잘 되지 않는 것이 정답이다).

(3) 논리연산자가 달라요!

&& ||(broken bar)가 and, or 인데 안된다. 음 ‘&’ ‘|’이다. 매틀랩에선 하나이다. 다른 프로그램에선 대부분 두 개인데 …

조건문

1. if 문

(1) 조건이 만족하면(true, 1) 명령문(들)을 실행하고 아니면 실행하지 않고 지나간다.

if 조건 명령문 (명령문) ... ... ...

end

x > 2 ?

명령문(들) Yes

No

(8)

(2) (if)조건이 맞으면 명령문(들) 을 실행하고 그렇지 않으면(else) 다른 명령문(들)을 실행한다.

if 조건 명령문 명령문 ... ... ...

else

다른 명령문 다른 명령문 ... ... ...

end

(3) 조건 1이 맞으면 명령 1을 실행하고 아니면 다시 조건 2를 검사하여 맞으면 명령 2를 실행하고 둘 다 아니면 명령 3을 실행한다.

if 조건 1 명령문 1 elseif 조건 2 명령문 2 elseif 조건 3 명령문 3 ... ... ...

end

주의 :

(1) 'elseif' 는 붙여 쓴다. 프로그램 언어에 따라 띄어쓰기도 한다.

(2) 괄호는 없다. 일반적인 언어에선 조건은 ( ), 실행문은 { }에 넣어 범위를 표시한다.

x > 2 ?

명령문(들) Yes

No

다른 명령문(들)

조건 1 ? Yes 명령문(들) 1

No

명령문(들) 2

No

Yes

명령문(들) 3 조건 2 ?

(9)

다른 언어의 예;

if (x>2) { y = x .^ 2;

}

(3) 끝날때 'end'를 붙인다. 위와 같이 다른 언어에선 { } 로 끝을 알 수 있다.

switch_case 문

여러 조건에 따라 여러 곳으로 나누어 갈 때 사용한다. case 문에선 크다 작다 등을 사용하지 못하고 단지 정확히 같을 조건만 쓸 수 있다.

switch x case 1 y=x;

case 2 y=x*x;

otherwise y=0;

end

no==1 no==2

no==1 no==3

위 조건이 모두 맞지 않음

(10)

반복문

1. for 문

for 반복조건 반복할 명령문 1 반복할 명령문 2 ... ... ...

end

(exam) sum=0;

for i=1:10 sum=sum+i;

end sum

(설명) 1 에서 10 까지의 합을 구하는 프로그램

sum=0; % 누적값을 반복적으로 구하는데 초기값을 먼저 설정해야 한다.

for i=1:10 % 반복조건으로 i 가 1 에서 1씩(기본 증분) 증가하여 10이 될 때까지 반복

% 따라서 모두 (10 - 1) + 1 = 10 회 반복한다.

% for 문은 반복회수를 정하는 이외에 index를 증가(감소)시키며 이를

% 사용하는 것이 일반적이다.

% i=1:10 은 행렬에서 나오는 콜론 연산자가 아니다(i 는 벡터 X, 스칼라 O) sum=sum+i;% i 값은 증가하고 이를 sum 에 누적해가는 계산

end % for 문의 끝에 넣는다. 다른 프로그램에선 { }

sum % 계산된 sum 을 출력한다. ';'을 붙이면 출력하지 않는다.

2. while 문

while 반복조건

i=1:10

명령문(들) 반복 Yes

반복 No

(11)

실행문

(counter 값 증가) % for 문에서 쓰는 counter 를 여기선 만들어 사용한다.

반복(loop)을 빠져나갈 방법으로 조건문 있을 수 있다

(while 조건이 무조건 true, 1 이면 무한 반복에 빠지므로 여기서 빠져나갈 조건문이 필수) end

(exam 1) sum=0; i=0;

while i<=10 sum=sum+i;

i=i+1;

end sum

while 문에서 반복조건에 맞으면 반복 실행하고 조건에 맞지 않으면 반복실행을 중단한다.

실행 조건은 i<=10 이므로 i 가 증가하여 10이 될 때까지 반복하고 11이 되면 실행을 중단하고 다음 과정으로 넘어간다.

(exam 2) sum=0; i=0;

while 1 i=i+1;

if i>=11 break;

end sum=sum+i;

end sum

while 1 은 무한 반복문이다. '1'이 true 이므로 무한 loop로 들어간다.

i<=10

명령문(들) 조건 OK

조건 No

i>=11 명령문(들)

조건 OK

조건 No

(12)

실행문 중간에 빠져나갈 조건문이 있어야 한다. 반복하지 않고 빠져나갈 조건이 만족하면 break;

문을 써서 반복 loop 에서 벗어난다.

물론 while 에 반복조건이 있어도 중간에 빠져나갈 조건문을 쓸 수 있다.

하여튼 while 문에서 실수로 무한 반복 오류가 발생할 수 있으므로 for loop 를 쓰면 그러한 오류는 피할 수 있다.

위 예문에서 모두 10번 반복하나 반복 후의 index(또는 counter) 값은 for 문은 10, while 문은 11로 된다. while 문에서 i=11 까지 된 후 조건을 검사하여 중단하기에 i 값은 반복회수와 다르게 된다.

2015-06-25, 곽노태

참조

관련 문서

이 break와 continue는 반복문을 제어하는 키워드로 반복문 실행 중에 반복 실행을 종료하고 싶을 때에는 break를, 반복문 루프 내의 나머지 실행부를 건너뛰고

▪ 여러 개의 조건문을 이용한 중첩 조건문을 사용하여 더 복잡한 상황에 맞게 사용할 수 있다. ▪ If-elif-else문은 실행 시간이 짧아진다는

case의 비교 값과 일치하는 것이 없으면 default 문 실행. default

정하는 주체는 실질적인 투자자들이 아니라

실작업 시간 이외에 생산된 물량은 포함 되지 않은 가장 직접적인 실적평가 자료 로

estrogen 대체 요법은 bone mass를 증가, 뇨 배출 감소, 골절 비율 감 소 등의 효과를 나타내며, calcium 단독 사용 시보다 bone mass 유지에 더 효과적이다.. 그러나 자궁암과

이번 역은 시청 시청역입니다 인천이나 수원으로 가실 분은 이번 ,.. 역에서 일호선으로 갈아타시기 바랍니다

→ 이미지의 사용 목적에 맞는 적절한 압축 알고리즘을