1절  자료구조와 알고리즘

<!--[if !supportLists]-->1.     <!--[endif]-->자료구조

<!--[if !supportLists]-->1)    <!--[endif]-->자료와 정보

<!--[if !supportLists]-->u  <!--[endif]-->자료를 얼마나 효율적으로 표현하고 관리할 것인가!

<!--[if !supportLists]-->u  <!--[endif]-->자료 : 단순한 관찰이나 측정을 통해 수집된 사실이나 어떤 값

<!--[if !supportLists]-->u  <!--[endif]-->정보 : 자료들을 특정 목적을 위하여 가공 및 처리하여 실제 문제에 도움이 되는 유용한 형태로 변환한 것

 

<!--[if !supportLists]-->2)    <!--[endif]-->자료구조

<!--[if !supportLists]-->u  <!--[endif]-->정의 : 자료를 효율적으로 사용하기 위해서 자료의 특성에 따라서 분류하여 구성하고 저장 및 처리하는 모든 작업

<!--[if !supportLists]-->u  <!--[endif]-->데이터를 효율적으로 표현하고 저장하기 위해 구조화 하는 것

<!--[if !supportLists]-->u  <!--[endif]-->자료의 사용 방법이나 성격에 따라 효율적으로 사용하기 위해 자료를 조직하고 저장하는 방법

<!--[if !supportLists]-->u  <!--[endif]-->알고리즘을 구성하는 부품(component)

<!--[if !supportLists]-->u  <!--[endif]-->기억 장치에 자료를 보관할 때 처리할 작업의 종류에 따라 적절한 자료 보관 방법인 자료구조를 선택

<!--[if !supportLists]-->u  <!--[endif]-->알고리즘 : 자료들을 처리하기 위한 일련의 절차와 방법. 자료 처리 절차 모임

<!--[if !supportLists]-->u  <!--[endif]-->프로그램 = 자료구조 + 알고리즘

 

<!--[if !supportLists]-->3)    <!--[endif]-->자료의 형태에 따른 분류

<!--[if !supportLists]-->u  <!--[endif]-->단순구조 : 정수, 실수, 문자, ,문자열

<!--[if !supportLists]-->u  <!--[endif]-->선형구조 : 리스트, 연결 리스트, 스택, , 데크

<!--[if !supportLists]-->u  <!--[endif]-->비선형구조 : 트리, 그래프

<!--[if !supportLists]-->u  <!--[endif]-->파일구조 : 순차 파일, 색인 파일, 직접 파일

<!--[if !supportLists]-->u  <!--[endif]-->자료구조 선택 시 고려 요소

<!--[if !supportLists]-->o  <!--[endif]-->포함된 데이터의 양

<!--[if !supportLists]-->o  <!--[endif]-->데이터를 사용하는 방법과 횟수

<!--[if !supportLists]-->o  <!--[endif]-->데이터의 정적 혹은 동적인 특성

<!--[if !supportLists]-->o  <!--[endif]-->자료구조에 의해 요구되는 기억 장치의 양

<!--[if !supportLists]-->o  <!--[endif]-->하나의 데이터를 수정하는데 걸리는 시간

<!--[if !supportLists]-->o  <!--[endif]-->프로그래밍의 복잡도

 

<!--[if !supportLists]-->4)    <!--[endif]-->자료의 단위와 종류

<!--[if !supportLists]-->u  <!--[endif]-->전기적 펄스에 의해 수의 처리 이루어짐!

<!--[if !supportLists]-->(1)   <!--[endif]-->비트 (bit)

<!--[if !supportLists]-->o  <!--[endif]-->최소 단위. 2진수 0 또는 1

<!--[if !supportLists]-->o  <!--[endif]-->on, off / 참 거짓 등

<!--[if !supportLists]-->(2)   <!--[endif]-->니블 (nibble)

<!--[if !supportLists]-->o  <!--[endif]-->4bit , 16개 정보 저장 (<!--[if !msEquation]--> <!--[endif]-->)

<!--[if !supportLists]-->(3)   <!--[endif]-->바이트 (byte)

<!--[if !supportLists]-->o  <!--[endif]-->8bit , 256개 정보 저장 (<!--[if !msEquation]--> <!--[endif]-->)

<!--[if !supportLists]-->o  <!--[endif]-->하나의 문자를 표현하는 기본 단위

<!--[if !supportLists]-->o  <!--[endif]-->정보의 기본 단위

<!--[if !supportLists]-->(4)   <!--[endif]-->문자 (character)

<!--[if !supportLists]-->o  <!--[endif]-->단어 구성 요소

<!--[if !supportLists]-->o  <!--[endif]-->7bit ~ 8bit정도

<!--[if !supportLists]-->(5)   <!--[endif]-->단어 (word)

<!--[if !supportLists]-->o  <!--[endif]-->바이트의 모임 (보통 2byte)

<!--[if !supportLists]-->o  <!--[endif]-->컴퓨터 내부의 명령 처리 단위

<!--[if !supportLists]-->o  <!--[endif]-->컴퓨터 주기억 장치와 기타 장치 사이에 전송되는 비트의 모임

<!--[if !supportLists]-->(6)   <!--[endif]-->필드 (field)

<!--[if !supportLists]-->o  <!--[endif]-->파일을 구성하는 최소 단위. 항목!(item)

<!--[if !supportLists]-->o  <!--[endif]-->레코드를 구성하는 논리적 자료 단위

<!--[if !supportLists]-->o  <!--[endif]-->보다 의미 있는 정보를 구성하는 최소 단위

<!--[if !supportLists]-->(7)   <!--[endif]-->레코드 (record)

<!--[if !supportLists]-->o  <!--[endif]-->하나 이상의 필드들이 모여서 구성된 자료 처리 단위

<!--[if !supportLists]-->o  <!--[endif]-->서로 관련 있는 필드들이 모여서 레코드 구성

<!--[if !supportLists]-->(8)   <!--[endif]-->파일 (file)

<!--[if !supportLists]-->o  <!--[endif]-->여러 개의 레코드가 모여 구성

<!--[if !supportLists]-->o  <!--[endif]-->디스크 저장 단위

<!--[if !supportLists]-->o  <!--[endif]-->프로그램 구성의 기본 단위

<!--[if !supportLists]-->u  <!--[endif]-->자료

<!--[if !supportLists]-->o  <!--[endif]-->수치 자료 : 사칙 연산의 대상이 되는 자료

<!--[if !supportLists]-->o  <!--[endif]-->비수치 자료 : 문자 데이터(ASCII 7bit, EBCDIC 8bit), 논리 자료

<!--[if !supportLists]-->o  <!--[endif]-->기억장치에는 바이트, 비트 단위로 주소가 할당

<!--[if !supportLists]-->o  <!--[endif]-->주소를 가지고 자료를 읽고 쓰는 등 처리 함

 

<!--[if !supportLists]-->2.     <!--[endif]-->알고리즘

<!--[if !supportLists]-->1)    <!--[endif]-->알고리즘의 개요

<!--[if !supportLists]-->u  <!--[endif]-->주어진 문제를 해결하기 위한 문제 해결 과정을 묘사하는 것

<!--[if !supportLists]-->u  <!--[endif]-->절차와 방법, 명령 등을 명확하게 기술해 놓은 것

<!--[if !supportLists]-->u  <!--[endif]-->프로그램이 만들어진 목적대로 작업을 수행하도록 하는 것

<!--[if !supportLists]-->u  <!--[endif]-->문제를 해결할 수 있는 잘 정의된 유한 시간 내에 종료되는 체계적인 절차

<!--[if !supportLists]-->o  <!--[endif]-->잘 정의된 : 알고리즘 읽었을 때 누구나 동일한 내용으로 이해 가능하도록 기술

<!--[if !supportLists]-->o  <!--[endif]-->유한 시간 내 종료 : 알고리즘 적용해 유한 시간 내 문제를 해결해 결과를 구함

<!--[if !supportLists]-->o  <!--[endif]-->즉, 출력 결과를 얻는 과정!

<!--[if !supportLists]-->u  <!--[endif]-->알고리즘의 요구조건

<!--[if !supportLists]-->o  <!--[endif]-->입력 : 외부에서 제공되는 0개 이상의 입력 데이터가 존재

<!--[if !supportLists]-->o  <!--[endif]-->출력 : 입력 값으로부터 적어도 하나 이상의 결과가 출력되어야 함

<!--[if !supportLists]-->o  <!--[endif]-->명확성 : 기술된 명령들이 모호하지 않고 명확해야 함

<!--[if !supportLists]-->o  <!--[endif]-->유한성 : 제한된 수의 명령 단계를 거친 후에는 반드시 종료해야 됨

<!--[if !supportLists]-->o  <!--[endif]-->유효성 : 모든 명령은 실행 가능해야 함

 

<!--[if !supportLists]-->2)    <!--[endif]-->알고리즘 기술 방법

<!--[if !supportLists]-->(1)   <!--[endif]-->자연어

<!--[if !supportLists]-->o  <!--[endif]-->사람이 사용하는 문장으로 설명

<!--[if !supportLists]-->o  <!--[endif]-->쉽고 편리 / 길어질 수 있고 의미 애매할 수 있음

<!--[if !supportLists]-->o  <!--[endif]-->복잡한 알고리즘 기술 시 부적절

<!--[if !supportLists]-->(2)   <!--[endif]-->순서도

<!--[if !supportLists]-->o  <!--[endif]-->명령의 종류와 기능에 따라 도표를 만들고 명령들의 순서대로 도표를 나열해 표현

<!--[if !supportLists]-->o  <!--[endif]-->작업의 연관 관계와 선후 관계를 시각적으로 보여줌

<!--[if !supportLists]-->o  <!--[endif]-->프로그램 작성의 직접적인 자료가 됨

<!--[if !supportLists]-->o  <!--[endif]-->이해 용이, 전달 용이

<!--[if !supportLists]-->o  <!--[endif]-->프로그램 정확성 여부 판단하는 자료

<!--[if !supportLists]-->o  <!--[endif]-->오류 발생 시 수정 간편

<!--[if !supportLists]-->(3)   <!--[endif]-->의사코드

<!--[if !supportLists]-->o  <!--[endif]-->프로그램 코드와 유사한 형식을 갖는 코드

<!--[if !supportLists]-->o  <!--[endif]-->특정 프로그래밍 언어의 문법에 따라 쓰이지 않고 일반적 언어로 코드를 흉내 낸 것

<!--[if !supportLists]-->o  <!--[endif]-->가장 선호되는 표기법

<!--[if !supportLists]-->o  <!--[endif]-->일반적으로 C언어 형식으로 작성

<!--[if !supportLists]-->(4)   <!--[endif]-->프로그래밍 언어

<!--[if !supportLists]-->o  <!--[endif]-->알고리즘 가장 정확히 표현하는 방법

<!--[if !supportLists]-->o  <!--[endif]-->구현 위해 구체적인 사항이 많아 알고리즘 전체 내용 파악에 어려울 수 있음

 

<!--[if !supportLists]-->2절  <!--[endif]-->자료 추상화

<!--[if !supportLists]-->l  <!--[endif]-->추상화

<!--[if !supportLists]-->n  <!--[endif]-->불필요한 부분을 삭제하거나 중요한 특징을 찾아낸 후 간단하게 표현.

<!--[if !supportLists]-->n  <!--[endif]-->필수적이고 중요한 속성만을 골라서 일반화 시키는 과정

<!--[if !supportLists]-->n  <!--[endif]-->여러 문제를 하나로 통합해 가는 과정

<!--[if !supportLists]-->n  <!--[endif]-->정보 은닉의 개발 : 사용자에게 중요한 정보 강조, 세부 사항은 제거

 

<!--[if !supportLists]-->l  <!--[endif]-->추상 자료형

<!--[if !supportLists]-->n  <!--[endif]-->정의 : 자료형의 일반화. 추상적으로 정의된 자료형

<!--[if !supportLists]-->n  <!--[endif]-->의의 : 구현으로부터 명세의 분리

<!--[if !supportLists]-->n  <!--[endif]-->데이터가 무엇이고 무슨 기능을 수행하는가 만을 정의

<!--[if !supportLists]-->n  <!--[endif]-->데이터 구조 및 연산의 구현 방법은 불포함(프로그램 언어마다 구현 방법이 다름)

<!--[if !supportLists]-->n  <!--[endif]-->객체와 연산을 정의

<!--[if !supportLists]-->n  <!--[endif]-->일반 자료형 이 외에 내가 필요한 자료형을 추상적으로 표현한 것

<!--[if !supportLists]-->n  <!--[endif]-->사물이나 현상을 데이터적 측면과 기능적 측면으로 나누어 표현한 것

<!--[if !supportLists]-->n  <!--[endif]-->구현에 관한 세부사항은 외부에서 모르게 하고 외부에서 간단한 인터페이스만 제공

<!--[if !supportLists]-->n  <!--[endif]-->사용자는 공개된 인터페이스만 사용, 구현 방법은 알 필요 없음 -> 정보 은닉

 

<!--[if !supportLists]-->3절  <!--[endif]-->SPARKS

<!--[if !supportLists]-->l  <!--[endif]-->알고리즘 기술에 사용되는 언어의 일종

<!--[if !supportLists]-->l  <!--[endif]-->PASCAL이나 C언어 등 구조화 된 프로그램 언어로 쉽게 변환

 

<!--[if !supportLists]-->1.     <!--[endif]-->선언문 (비실행문)

<!--[if !supportLists]-->n  <!--[endif]-->프로그램의 일반적인 특성과 그 프로그램을 다루는 데이터의 특성을 지정하는 비실행문

 

<!--[if !supportLists]-->2.     <!--[endif]-->지정문

<!--[if !supportLists]-->n  <!--[endif]-->상수나 변수 또는 연산식의 결과를 변수에 지정하는 문장

<!--[if !supportLists]-->n  <!--[endif]-->변수 ; (: 대입 연산자)

 

<!--[if !supportLists]-->3.     <!--[endif]-->조건문

<!--[if !supportLists]-->n  <!--[endif]-->if

<!--[if !supportLists]-->n  <!--[endif]-->주어진 조건이 참이냐 거짓이냐에 따라 다른 명령 처리하도록 만든 수행문

<!--[if !supportLists]-->n  <!--[endif]-->if (조건식1) – then (A) – else if(조건식2) – then (B) – else (C)

if (조건식1) then

      명령문 1;

else if (조건식2) then // 다중 조건문

      명령문 2;

...

else

      명령문 n;

endif

 

<!--[if !supportLists]-->4.     <!--[endif]-->case

<!--[if !supportLists]-->n  <!--[endif]-->여러 조건식 중 해당 조건 찾아 그에 대한 명령문 수행

<!--[if !supportLists]-->n  <!--[endif]-->if문보다 가독성이 높음

case {

      조건식 1 : 명령문 1;

      조건식 2 : 명령문 2;

      조건식 n : 명령문 n;

      else : 명령문 n+1;

}

 

<!--[if !supportLists]-->5.     <!--[endif]-->반복문

<!--[if !supportLists]-->1)    <!--[endif]-->for

<!--[if !supportLists]-->u  <!--[endif]-->반복 횟수를 지정 / 반복 끝내는 종료 조건 제시

<!--[if !supportLists]-->u  <!--[endif]-->반복하는 부분을 제어하기 위해 초기값, 조건식, 증감값 등 세 부분으로 구성

for (초기값; 조건식; 증감값)

            명령문;

 

for (초기값; 조건식; 증감값)

{

    명령문;

}

 

<!--[if !supportLists]-->2)    <!--[endif]-->while

<!--[if !supportLists]-->u  <!--[endif]-->조건식이 참인 동안 명령문 반복 수행

<!--[if !supportLists]-->u  <!--[endif]-->처음부터 조건식이 거짓이면 명령문 수행 없이 while문 빠져나옴

while (조건식)

           명령문;

 

<!--[if !supportLists]-->6.     <!--[endif]-->procedure

<!--[if !supportLists]-->n  <!--[endif]-->처리할 작업 별로 작은 단위 프로그램을 여러 개 구성하는 것

<!--[if !supportLists]-->n  <!--[endif]-->하나의 프로그램 안에 기능A가 여러 번 실행하는 구조를 가진 경우 기능 A를 하나의 단위로 만들 수 있음. -> 프로시저로 작성 가능

<!--[if !supportLists]-->n  <!--[endif]-->특정 작업을 수행하기 위한 프로그램의 일부. 필요 시 호출하여 사용

<!--[if !supportLists]-->n  <!--[endif]-->일련의 반복적인 명령을 수행하는 블록을 별도의 블록으로 표현한 것

<!--[if !supportLists]-->n  <!--[endif]-->서브루틴이나 함수가 될 수 있음

<!--[if !supportLists]-->n  <!--[endif]-->procedure NAME (parameter list)

명령문

end

 

<!--[if !supportLists]-->7.     <!--[endif]-->프로시저 간 자료 전달 방법

<!--[if !supportLists]-->n  <!--[endif]-->실 매개변수와 형식 매개변수가 필요

<!--[if !supportLists]-->n  <!--[endif]-->실 매개변수 : 프로시저에 전달되는 실제 값을 저장하고 있는 인자

<!--[if !supportLists]-->n  <!--[endif]-->형식 매개변수 : 프로시저 선언에 사용하는 인자

<!--[if !supportLists]-->1)    <!--[endif]-->call by value

<!--[if !supportLists]-->u  <!--[endif]-->실 매개변수 값 자체를 서브 프로시저의 형식 매개변수에 전달

<!--[if !supportLists]-->u  <!--[endif]-->호출된 프로시저에서 지역변수처럼 취급 -> main 함수에 선언된 변수 값 변경 X

<!--[if !supportLists]-->u  <!--[endif]-->변수 값을 변경시켜 프로시저에 전달 -> 원본 데이터 손상 X

 

<!--[if !supportLists]-->2)    <!--[endif]-->call by reference

<!--[if !supportLists]-->u  <!--[endif]-->실 매개변수 값이 저장된 기억 장소를 가리키는 포인터나 실제 수로를 형식 매개변수에 전달

<!--[if !supportLists]-->u  <!--[endif]-->형식 매개변수가 간접 주소법을 이용하여 실 매개변수 참조

<!--[if !supportLists]-->u  <!--[endif]-->형식 매개변수 값 변경 -> 대응 실 매개변수 값도 변경

 

<!--[if !supportLists]-->3)    <!--[endif]-->call by name

<!--[if !supportLists]-->u  <!--[endif]-->형식 매개변수의 이름이 사용될 때마다 그에 대응되는 실 매개변수의 이름으로 대치됨

<!--[if !supportLists]-->u  <!--[endif]-->형식 매개변수가 사용되는 시점에서 대응되는 실 매개변수의 값이나 기억 장소 위치를 구해 사용

 

<!--[if !supportLists]-->8.     <!--[endif]-->입 출력문

<!--[if !supportLists]-->n  <!--[endif]-->read : 데이터 값을 입력 받을 때 사용

<!--[if !supportLists]-->n  <!--[endif]-->print : 변수의 내용이나 계산 결과 출력할 때 사용

<!--[if !supportLists]-->n  <!--[endif]-->read(argument list)

print(argument list)

 

<!--[if !supportLists]-->9.     <!--[endif]-->기타 명령과 규칙

<!--[if !supportLists]-->1)    <!--[endif]-->주석

<!--[if !supportLists]-->u  <!--[endif]-->// 이나 /* */

<!--[if !supportLists]-->2)    <!--[endif]-->stop

<!--[if !supportLists]-->u  <!--[endif]-->현재 진행 중인 프로그램을 중단하는 구문

<!--[if !supportLists]-->u  <!--[endif]-->프로시저 안의 어느 곳에서든 stop문 사용 가능

<!--[if !supportLists]-->3)    <!--[endif]-->SPARKS 언어 사용 규칙

<!--[if !supportLists]-->u  <!--[endif]-->변수 의미 알 수 있게 정의

<!--[if !supportLists]-->u  <!--[endif]-->프로시저의 입출력 변수 명확히 명시

<!--[if !supportLists]-->u  <!--[endif]-->제어흐름 되도록 순차적으로

<!--[if !supportLists]-->u  <!--[endif]-->들여쓰기

<!--[if !supportLists]-->u  <!--[endif]-->주석 짧고 명확하게

<!--[if !supportLists]-->u  <!--[endif]-->함수 적절히 사용

 

<!--[if !supportLists]-->4절  <!--[endif]-->순환 알고리즘

<!--[if !supportLists]-->l  <!--[endif]-->순환(recursion) :

<!--[if !supportLists]-->n  <!--[endif]-->정의하려는 개념 자체를 정의 속에 포함하여 사용하는 방법 (자신의 정의에 자신을 다시 사용)

<!--[if !supportLists]-->n  <!--[endif]-->문제 내에 문제 자체의 작은 형태가 또 존재하는 형태로 자기 자신을 다시 호출하여 문제를 해결하는 기법

<!--[if !supportLists]-->n  <!--[endif]-->어떤 문제에 크기만 다를 뿐 성격이 똑 같은 작은 형태의 문제들이 포함된 것(점근적 접근)

<!--[if !supportLists]-->n  <!--[endif]-->알고리즘이나 함수가 수행 도중 자기 자신을 다시 호출하여 문제를 해결하는 기법

<!--[if !supportLists]-->n  <!--[endif]-->하나의 문제 내에 매개변수만 다른 동일한 문제가 있을 때 사용

<!--[if !supportLists]-->n  <!--[endif]-->프로그램 단순화, 명료. 함수의 정의 단순하게 표현 가능

<!--[if !supportLists]-->n  <!--[endif]-->순환의 정의에서 초기의 조건을 잘 정리해야 함

<!--[if !supportLists]-->l  <!--[endif]-->직접 순환 : 함수가 직접 자신을 호출

<!--[if !supportLists]-->l  <!--[endif]-->간접 순환 : 다른 제 3의 함수를 호출하고 그 함수가 다시 자신을 호출하는 방법

<!--[if !supportLists]-->l  <!--[endif]-->순환 호출을 종료하는 조건을 추가해 줘야 함 -> 무한 호출 방지

<!--[if !supportLists]-->l  <!--[endif]-->반복문으로 바꾸어 작성 가능

 

<!--[if !supportLists]-->5절  <!--[endif]-->성능 분석

<!--[if !supportLists]-->l  <!--[endif]-->자원 : 소요 시간, 메모리, 통신 대역 등

<!--[if !supportLists]-->l  <!--[endif]-->효율적인 알고리즘 : 전체 실행 시간이 짧고 메모리 같은 컴퓨터 자원을 적게 사용하는 알고리즘

<!--[if !supportLists]-->l  <!--[endif]-->알고리즘 복잡도 분석!

<!--[if !supportLists]-->1.     <!--[endif]-->공간 복잡도

<!--[if !supportLists]-->n  <!--[endif]-->알고리즘이 수행될 때 필요한 메모리 공간

<!--[if !supportLists]-->n  <!--[endif]-->알고리즘을 프로그램으로 실행시켜 완료하는 데 까지 소요되는 총 저장 공간

<!--[if !supportLists]-->n  <!--[endif]-->공간 복잡도 = 고정공간 + 가변공간

<!--[if !supportLists]-->u  <!--[endif]-->고정 공간 : 프로그램 크기나 입출력 횟수와 관계 없이 고정적으로 필요한 저장 공간

<!--[if !supportLists]-->u  <!--[endif]-->가변 공간 : 실행 과정에서 자료구조와 변수들이 필요로 하는 저장 공간

<!--[if !supportLists]-->n  <!--[endif]-->대용량 컴퓨터가 많아지며 공간 복잡도 중요성 낮아짐

 

<!--[if !supportLists]-->2.     <!--[endif]-->시간 복잡도

<!--[if !supportLists]-->n  <!--[endif]-->알고리즘을 실행시켜 완료하는 데까지 걸리는 시간

<!--[if !supportLists]-->n  <!--[endif]-->알고리즘을 이루고 있는 연산들이 몇 번 실행되는지 숫자로 표시 연산의 실행 횟수

<!--[if !supportLists]-->n  <!--[endif]-->시간 복잡도 = 컴파일 시간 + 실행 시간

<!--[if !supportLists]-->u  <!--[endif]-->컴파일 시간 : 프로그램마다 거의 고정적인 시간 소요

<!--[if !supportLists]-->u  <!--[endif]-->실행 시간 : 명령문의 실행 빈도수에 따라 계산

<!--[if !supportLists]-->o  <!--[endif]-->하나의 단위 시간 : 지정문, 조건문, 반복문 내의 제어문과 반환문

<!--[if !supportLists]-->o  <!--[endif]-->실행 시간 좌우 하는 것 : for 루프 횟수, 특정 행이 수행되는 횟수, 함수 호출 횟수

<!--[if !supportLists]-->n  <!--[endif]-->연산 횟수를 시간 복잡도로 계산했을 때 장점

<!--[if !supportLists]-->u  <!--[endif]-->코딩, 실행이 필요하지 않음

<!--[if !supportLists]-->u  <!--[endif]-->하드웨어, 소프트웨어 필요하지 않음 -> 의사코드로 충분히 계산 가능

<!--[if !supportLists]-->u  <!--[endif]-->모든 플랫폼에서 동일한 결과 산출

<!--[if !supportLists]-->n  <!--[endif]-->실제 실행 시간을 시간 복잡도로 계산했을 때 단점

<!--[if !supportLists]-->u  <!--[endif]-->측정을 위한 완성된 프로그램이 필요

<!--[if !supportLists]-->u  <!--[endif]-->모든 플랫폼에서 동일한 결과 산출하지 못함

 

<!--[if !supportLists]-->3.     <!--[endif]-->연산 시간 표기법

<!--[if !supportLists]-->n  <!--[endif]-->점근적 분석법

<!--[if !supportLists]-->u  <!--[endif]-->입력의 크기가 충분히 큰 경우에 대한 분석

<!--[if !supportLists]-->u  <!--[endif]-->데이터의 개수 n이 무한대가 될 떄 수행 시간이 증가하는 증가율을 시간 복잡도로 표현

<!--[if !supportLists]-->u  <!--[endif]-->최고차항의 차수만으로 표시 -> 가장 자주 실행되는 연산 혹은 문장의 실행 횟수 고려

<!--[if !supportLists]-->o  <!--[endif]-->가장 큰 항의 영향이 절대적이고 다른 항은 무시될 정도로 작아짐

<!--[if !supportLists]-->u  <!--[endif]-->어떤 함수의 증가 혹은 감소 양상을 다른 간단한 함수와 비교로 표현하는 방법

 

<!--[if !supportLists]-->1)    <!--[endif]-->빅-(Big-O) 표기법

<!--[if !supportLists]-->u  <!--[endif]-->실행 시간 함수의 값에 가장 큰 영향을 주는 n에 대한 항을 선택하여 계수 생략

<!--[if !supportLists]-->u  <!--[endif]-->O(Big-O)로 표현

<!--[if !supportLists]-->u  <!--[endif]-->입력 데이터가 최악일 때 알고리즘이 보이는 효율 기준

<!--[if !supportLists]-->u  <!--[endif]-->f(n) g(n)이 주어졌을 때 모든 <!--[if !msEquation]--> <!--[endif]-->에 대하여 f(n) cg(n)을 만족하는 상수 c와 <!--[if !msEquation]--> <!--[endif]-->가 존재하면 f(n) = O(g(n))이다.

u  점근적 상한선

<!--[if !supportLists]-->o 를 기준으로 보다 오른쪽에 있는 모든 n값에 대해 

    함수 f(n)은 함수 cg(n)보다 작거나 같다.

<!--[if !supportLists]-->o  <!--[endif]-->아무리 나빠도 비교하는 함수와 같거나 좋다.


<!--[if !supportLists]-->u  <!--[endif]-->주어진 함수의 가장 높은 차수의 항을 사용하고 계수는 1로 함

<!--[if !supportLists]-->u  <!--[endif]-->정보의 손실이 일어날 수 있음 -> 엄밀하지 않음

<!--[if !supportLists]-->u  <!--[endif]-->길어야 이정도 시간이면 된다! -> 가장 근접한 상한 사용

<!--[if !supportLists]-->u  <!--[endif]-->복잡도 순서 : O(1) < O(logn) < O(n) < O(nlogn) < O() < O() < O() < O(n!)

<!--[if !supportLists]-->o  <!--[endif]-->O(1)

상수 시간

<!--[if !supportLists]-->o  <!--[endif]-->O()

제곱 시간

<!--[if !supportLists]-->o  <!--[endif]-->O(logn)

로그 시간

<!--[if !supportLists]-->o  <!--[endif]-->O()

세제곱 시간

<!--[if !supportLists]-->o  <!--[endif]-->O(n)

선형 시간

<!--[if !supportLists]-->o  <!--[endif]-->O()

지수 시간

<!--[if !supportLists]-->o  <!--[endif]-->O(nlogn)

로그 선형 시간

<!--[if !supportLists]-->o  <!--[endif]-->O(n!)

계승 시간


2)    <!--[endif]-->빅-오메가(Big- ) 표기법

<!--[if !supportLists]-->u  <!--[endif]-->f(n) g(n)이 주어졌을 때 모든 <!--[if !msEquation]--> <!--[endif]-->에 대하여 f(n) cg(n)을 만족하는 상수 c와 <!--[if !msEquation]--> <!--[endif]-->가 존재하면 f(n) = Ω(g(n))이다.

<!--[if !supportLists]-->u  <!--[endif]-->점근적 하한선

<!--[if !supportLists]-->o  를 기준으로 보다 오른쪽에 있는 모든 n값에 대해 

    함수 f(n)은 함수 cg(n)보다 크거나 같다.

<!--[if !supportLists]-->o  <!--[endif]-->적어도 g(n)의 비율로 증가하는 함수

<!--[if !supportLists]-->o  <!--[endif]-->아무리 좋아도 비교하는 함수와 같거나 나쁘다.

<!--[if !supportLists]-->u  <!--[endif]-->최소한 이만한 시간은 걸린다!

 

<!--[if !supportLists]-->3)    <!--[endif]-->빅-세타(Big- Θ) 표기법

<!--[if !supportLists]-->u  <!--[endif]-->점근적 상한선과 점근적 하한선의 교집합

<!--[if !supportLists]-->u  <!--[endif]-->f(n) g(n)이 주어졌을 때 모든 <!--[if !msEquation]--> <!--[endif]-->에 대하여 c1g(n) f(n) c2g(n)을 만족하는 상수 c1, c2와 <!--[if !msEquation]--> <!--[endif]-->가 존재하면 f(n) = Θ(g(n))이다


o  를 기준으로 보다 오른쪽에 있는 모든 n값에 대해 

    함수 f(n)은 함수 c1g(n)보다 크거나 같고 c2g(n)보다 작거나 같다.

<!--[if !supportLists]-->o  <!--[endif]-->가장 정밀한 점근적 표기법

 

<!--[if !supportLists]-->4.     <!--[endif]-->실용적인 복잡도

<!--[if !supportLists]-->n  <!--[endif]-->최선의 경우, 평균적인 경우, 최악의 경우로 나누어 평가 가능

<!--[if !supportLists]-->n  <!--[endif]-->최대로 불리한 입력 데이터를 사용하는 최악의 경우의 실행 시간이 가장 중요

<!--[if !supportLists]-->o  <!--[endif]-->완만할수록 효율적

 


10 제어자

제어자(modifier)

○ 제어자 : 클래스, 변수 또는 메서드의 선언부에 함께 사용되며 부가적인 의미를 부여함

○ 접근제어자 : public, protected, default, private

○ 그 외 : static, final, abstract, native, transient, synchronizes, volatile, strictfp

○ 클래스나 멤버변수와 메서드에 주로 사용

○ 하나의 대상에 대해 여러 제어자 조합 사용 가능

접근 제어자는 네 개 중 한 개 사용 가능

○ 제어자 순서는 주로 접근 제어자를 제일 왼쪽에 놓음

 

● static – 클래스의, 공통적인

○ 의미 : 클래스의, 공통적인

static이 붙은 멤버변수와 메서드, 초기화 블록은 인스턴스가 아닌 클래스에 관계된 것 -> 인스턴스 생성 없이 사용 가능

static 사용 가능 : 멤버변수, 메서드, 초기화 블록

static

멤버변수

- 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 됨

- 클래스 변수는 인스턴스 생성하지 않고도 사용 가능

- 클래스가 메모리에 로드 될 때 생성

메서드

- 인스턴스를 생성하지 않고도 호출 가능한 static 메서드가 됨

- static메서드 내에서는 인스턴스 멤버 직접 사용할 수 없음

 

● final – 마지막의, 변경될 수 없는

○ 마지막의, 변경될 수 없는

○ 거의 모든 대상에 사용될 수 있음

 

 

 

l  final – 마지막의, 변경될 수 없는

m  마지막의, 변경될 수 없는

m  거의 모든 대상에 사용될 수 있음

○ 대표적인 final 클래스 : String, Math

○ 생성자를 이용한 final 변수 초기화

■ final이 붙은 변수는 상수이므로 보통 선언과 초기화를 동시에 함

인스턴스 변수의 경우 생성자에서 초기화 되도록 할 수 있음

클래스 내에 매개변수 갖는 생성자 선언해서 final변수 초기화

→ final이 붙은 멤버변수가 다른 값을 갖도록 할 수 있음

 

● abstract – 추상의, 미완성의

○ 추상의, 미완성의

○ 메서드의 선언부만 작성하고 실제 수행 내용은 구현하지 않은 추상 메서드 선언에 사용

○ 클래스 내에 추상 메서드가 존재하는지 알 수 있게 클래스에 사용

추상 클래스 : 아직 완성되지 않은 메서드가 존재하는 인스턴스 생성 불가한 클래스

○ 완성된 클래스지만 abstract 붙이는 경우 : 메서드는 있지만 클래스로 구현해봐야 쓸모 없는 클래스일 때 붙여서 인스턴스 생성 못하게 함

다른 클래스가 이 클래스 상속받아 일부 원하는 메서드만 오버라이딩 해도 되는 것이기에 나둠

 

접근 제어자

○ 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역학

○ 접근 제어자가 지정되어 있지 않다면 접근 제어자는 default

○ 접근 제어자가 사용될 수 있는 곳 : 클래스, 멤버변수, 메서드, 생성자

private : 같은 클래스 내에서만 접근 가능

default : 같은 패키지 안에서만 접근 가능

protected : 같은 패키지 안 + 다른 패키지의 자손 클래스에서 접근 가능

public : 접근 제한 없음

public > protected > default > private 

 

○ 접근 제어자를 이용한 캡슐화

접근 제어자 사용하는 이유

(1) 외부로부터 데이터를 보호하기 위해서

(2) 외부에서는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서

멤버변수를 private protected로 제한하고 멤버변수의 값을 읽고 변경할 수 있는 public 메서드를 제공 -> 간접적으로 멤버변수 값 다루기

멤버변수 다루는 메서드 : setter, getter

 

○ 생성자의 접근 제어자

싱글톤 !

생성자에 접근 제어자를 사용해서 인스턴스의 생성을 제어

생성자의 접근 제어자를 private 로 지정 -> 외부에서 생성자에 접근할 수 없음

클래스 내부에서 생성자 생성하는 public 메서드 만들어 그 메서드로 인스턴스 생성

생성자가 private인 클래스는 다른 클래스의 조상이 될 수 없음

자손 클래스 인스턴스 생성할 때 조상 클래스의 생성자를 불러올 수 없으므로

클래스 앞에 final 추가해서 상속할 수 없는 클래스라는 것을 알리는 것이 좋음

 

제어자의 조합

 

○ 제어자 조합 시 주의 사항

1)    메서드에 static abstract를 같이 사용할 수 없음

static 메서드는 몸통이 있는 메서드에서만 사용할 수 있음(abstract은 추상 메서드에 쓰니까)

2)    클래스에 abstract final을 동시에 사용할 수 없음

final은 확장할 수 없음/ abstract는 확장으로만(상속) 사용할 수 있음

3)    abstract메서드의 접근 제어자가 private일 수 없음

접근 제어자가 private면 상속이 안 되는데, abstract는 상속으로 완성해야 함

4)    메서드에 private final을 같이 사용할 필요 없음

접근 제어자가 private인 메서드는 오버라이딩 될 수 없고 final도 오버라이딩 할 수 없기 때문에 의미 중복

 

09 package import

패키지

○ 클래스의 묶음

클래스 또는 인터페이스를 포함시킬 수 있음

서로 관련된 클래스들끼리 그룹 단위로 묶어 놓아 클래스 관리 효율적

 

○ 같은 이름의 클래스라도 패키지가 다르면 다른 클래스!

클래스의 실제 이름은 패키지명도 포함되는 것!

 

○ 물리적으로 하나의 디렉토리

클래스도 물리적으로 하나의 클래스 파일임(.class)

어떤 패키지에 속한 클래스는 해당 디렉토리에 존재하는 클래스 파일이어야 함

패키지도 다른 패키지를 포함할 수 있음(구분 ‘ . ())

 

○ 패키지의 특징

1)    하나의 소스파일에는 첫 번째 문장으로 단 한 번의 패키지 선언만을 허용

2)    모든 클래스는 반드시 하나의 패키지에 속해야 함

3)    패키지는 점(.)을 구분자로 하여 계층구조로 구성할 수 있음

4)    패키지는 물리적으로 클래스파일을 포함하는 하나의 디렉토리

 

패키지의 선언

○ 클래스나 인터페이스의 소스파일에 “package 패키지명;” 적어줌

패키지 선언문은 반드시 소스파일에서 주석과 공백을 제외한 첫 번째 문장이어야 함

하나의 소스파일에 단 한번 선언될 수 있음

패키지명은 소문자로 적는 것이 원칙

 

○ 이름 없는 패키지(unnamed package)

모든 클래스는 반드시 하나의 패키지에 포함되어야 함

소스파일 작성할 때 패키지 선언 안하고 사용할 수 있는 것은 이름 없는 패키지 덕분

소스파일에 자신이 속할 패키지를 지정하지 않은 클래스는 자동적으로 ‘이름 없는 패키지’에 속하게 됨

결국 소스 파일은 패키지에 속한 샘이 되는 것

 

● import

○ 컴파일러에게 소스파일에서 사용된 클래스의 패키지에 대한 정보를 제공

소스 코드 작성 시 다른 패키지의 클래스 사용하려면 패키지명이 포함된 클래스 이름을 전부 사용해야 함

클래스의 코드 작성 전 import문으로 사용하고자 하는 클래스의 패키지를 미리 명시해줌

명시해주면 클래스명을 패키지까지 포함해서 쓰지 않아도 됨

 

import문은 프로그램 성능에 전혀 영향을 미치지 않음

 

import문의 선언

■ package문 다음, 클래스 선언문 이전에 위치

일반적인 소스파일(*.java)의 구성 순서

(1)   package

(2)   import

(3)   클래스 선언

■ import문 선언 방법

import 패키지명.클래스명 ;

import 패키지명. * ;

클래스의 이름 대신 *를 사용하기도 함

한 패키지의 여러 클래스 사용하는 경우는 *을 사용해 모든 클래스를 import

하위 패키지의 클래스까지 포함하지는 않음

마지막 패키지의 모든 클래스를 대표하는 것!

import java.util. * ; (가능)

import java. * ; (불가능)

■ System이나 String같은 java.lang 패키지의 클래스들은 모든 소스파일에 묵시적으로 import되어 있는 것

 

static import

■ static 멤버를 호출할 때 클래스 이름을 생략할 수 있음

특정 클래스의 static멤버를 자주 사용할 때 편리, 코드 간결

import static java.lang.Integer. * ; // Integer 클래스의 static 메서드

import static java.lang.Math.random; // Math.random(). 괄호 없이 사용

import static java.lang.System.out; // System.out out 만으로 참조 가능

이렇게 선언해 둔다면 아래 메서드가 간단해 짐

System.oyt.println(Math.random());

→ out.println(random());

 

'JAVA > 이론' 카테고리의 다른 글

[java][이론] 011 다형성  (0) 2020.08.06
[java][이론] 010 제어자  (0) 2020.07.08
[java][이론] 008 상속  (0) 2020.07.06
[java][이론] 007 생성자와 변수의 초기화  (0) 2020.07.04
[java][이론] 006 변수와 메서드  (0) 2020.07.02

08 상속

클래스 간의 관계 상속 / 포함

○ 상속

상속 : 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것

코드의 추가 및 변경 용이

코드 재사용성 높이고 코드 중복 제거

 

새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드 ‘extends’와 함께 써줌

조상 클래스 : 부모 클래스, 상위 클래스. 기반 클래스

자손 클래스 : 자식 클래스, 하위 클래스, 파생된 클래스

 

자손 클래스는 조상 클래스의 모든 멤버를 상속받음 -> 조상 클래스의 멤버를 포함함

조상 클래스가 변경되면 자손 클래스도 자동으로 영향 받음(그 반대는 아님)

자손 클래스는 항상 조상 클래스보다 같거나 많은 멤버를 가짐

상속에 상속을 거듭할수록 상속받는 클래스의 멤버 개수가 늘어남

 

상속 받는다! -> 조상 클래스를 확장한다 -> extends

생성자와 초기화 블록은 상속되지 않고, 멤버만 상속 됨

자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많음

접근제어자가 private 또는 default인 멤버들은 상속은 받지만 자손 클래스로부터의 접근이 제한됨

 

자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성 됨

자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버도 함께 생성됨

따로 조상 클래스 인스턴스를 생성하지 않고 조상 클래스 멤버 사용 가능

 

오버라이딩 : 조상 클래스에 정의된 메서드와 같은 메서드를 자손 클래스에서 정의하는 것(재정의)

단일 상속 : 자바는 단일 상속을 지원! 다중상속을 지원하지 않음

 

○ 포함

한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것

클래스 재사용의 한 방법

 

○ 관계 결정하기

상속 관계를 맺을 것인지, 포함 관계를 맺을 것인지 결정

상속 관계 : ~ ~이다. (is – a) ex) 원은 도형이다. Circle is a Shape.

포함 관계 : ~ ~을 가지고 있다 (has – a) ex) 원은 점을 가지고 있다. Circle has a Point.

 

Object 클래스 - 모든 클래스의 조상

모든 클래스의 상속 계층도의 최상위에 있는 조상 클래스

모든 클래스들은 자동적으로 Object클래스에서 상속 받게 됨

컴파일러가 자동적으로 ‘extends Object;를 추가함

 

오버라이딩

○ 오버라이딩 : 조상 클래스로부터 상속 받은 메서드의 내용을 자손 클래스에서 변경하는 것

상속 받은 메서드를 그대로 사용하기도 하지만, 자손 클래스에 알맞게 변경하기도 함

 

○ 오버라이딩의 조건

자손 클래스에서 오버라이딩 하는 메서드는 조상 클래스의 메서드와

(1)   이름이 같아야 함

(2)   매개변수가 같아야 함

(3)   반환 타입이 같아야 함

즉 선언부가 완전히 일치해야 함

 

접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경 가능

(1)   접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없음

(2)   조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없음

예외의 개수는 선언한 예외의 수뿐 아니라 더 넓은 범위의 예외도 포함

넓은 범위의 예외는 따지고 보면 더 많은 수의 예외를 선언한 것이 되므로

(3)   인스턴스 메서드를 static 메서드로 또는 그 반대로 변경할 수 없음

 

○ 오버로딩 vs. 오버라이딩

둘 다 메서드 이름은 같은데 말이지.

오버로딩 : 기존에 없는 새로운 메서드를 정의하는 것

메서드 이름은 같지만 매개변수가 달라서 전혀 다른 메서드임

매개변수로 구분이 가능함

오버라이딩 : 상속 받은 메서드의 내용을 변경하는 것

메서드 이름도 반환형도 매개변수도 싹 다 같음

상속 받은 자손 클래스만 사용 가능한 것

재정의!

 

super – 조상 클래스의 참조변수

자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는 데 사용되는 참조변수

(cf. this : 멤버변수와 지역변수의 이름이 같을 때 자기자신을 가리키는 참조변수)

상속 받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super 붙여 구분

 

조상 클래스의 멤버와 자손 클래스의 멤버가 중복 정의되었을 때만 사용하는 것이 좋음

■ super this

모든 인스턴스 메서드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장됨

그 것이 참조변수로 super this에 들어가는 것!

 

변수와 메서드 모두 super로 호출 가능

조상 클래스의 메서드를 자손 클래스에서 오버라이딩 한 경우 super 사용

■ super static메서드에 사용할 수 없음

static메서드는 인스턴스와 관련이 없음! (this도 마찬가지)

 

super() - 조상 클래스의 생성자

조상 클래스의 생성자를 호출하는 데 사용

자손 클래스의 인스턴스를 생성하면 자손의 멤버와 조상의 멤버가 모두 합쳐진 인스턴스가 생성됨 -> 자손 클래스 생성자에 조상 클래스 생성자가 호출 돼서 그런 것

■ Object 클래스를 제외한 모든 클래스의 생성자 첫 줄에 생성자 this(), super() 호출해야 함

그렇지 않으면 컴파일러가 자동으로 super();을 생성자 첫 줄에 삽입함

자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수 있으므로 조상 클래스 멤버가 먼저 초기화 되어 있어야 함

생성자가 정의되어 있는 클래스는 컴파일러가 기본 생성자를 자동으로 추가하지 않음

조상 클래스의 멤버변수는 조상의 생성자에 의해 초기화되도록 하는 것이 좋음

 

행렬의 곱셈은 어렵다 ㅎㅎㅎ

고등학교 때 제일 못했던 것이 행렬이어서 ㅜㅜㅜ 행렬 정말 싫다(수능 때 수학 1문제 틀렸는데 1번 행렬문제였다)

여튼 뭐 이거랑 그거랑은 다르니까. 난 더 이상 행렬 시험을 치지 않으니까..ㅜㅜ

 

참고하기. 행렬의 곱셈

2020/07/05 - [[개발 & 독학]/reference] - [고등수학] 행렬의 곱셈

 

조금 복잡하다.

알고리즘 할 때 이야기 하겠지만

행렬은 결합법칙이 성립하는데 결합하는 방향에 따라 속도가 많이 차이가 난다.

적게 계산할 수 있도록 만들어 줘야 되는데, 그 것은 나중에 포스팅 하게 되면 여기에 연결하도록 하곘다.

또 콘솔에서 입력받아서 자유도를 높이다보니 좀 복잡하다.

찬찬히 설명해도 모르겠으면 댓글 주시길 바란다.

 

1. 클래스 멤버 선언

곱하기 할 배열들을 미리 정의하자.

행렬을 2차원 배열이므로 저런식으로 초기화 해줬다.

Scanner scanner = new Scanner(System.in);

	int [][] a = {{4, 4, 5}, {3, 7, 2}}; // 2, 3
	int [][] b = {{7, 5, 1, 2}, {9, 6, 4, 3}, {4, 2, 1, 6}}; // 3, 4
	int [][] c = {{8, 4}, {5, 7}, {2, 3}, {9, 6}}; // 4, 2
	int [][] d = {{1, 4}, {9, 3}, {7, 6}}; // 3, 2
	
	// a * b , b * c , c * a

 

2. showArray(int[][] a)

배열을 보는 메서드를 정의한다.

void showArray(int[][] a) {
		for(int[] col : a) {
			for(int tmp : col) {
				System.out.print(tmp+" ");
			}
			System.out.println();
		}
		System.out.println();
	}

 

3. findArray(char ch)

콘솔에서 곱셈을 실행할 행렬을 직접 입력 받아서 그 행렬들 끼리 곱셈을 하도록 구현한다.

따라서 입력받은 문자를 내가 가진 행렬로 바꿔야 한다.

입력받은 문자를 매개변수로 하는 메서드이며

각 글자가 일치하는 행렬을 반환한다.

this는 멤버변수를 나타내는 참조변수이다. 이론에 나오니 확인해 보시길

2020/07/02 - [[JAVA]/이론] - [java][이론] 005 클래스와 객체

2020/07/04 - [[JAVA]/이론] - [java][이론] 007 생성자와 변수의 초기화

	int [][] findArray(char ch) {

		int [][] result = null;
		
		if(ch=='a'){
			result = this.a;			
		} else if(ch=='b'){
			result = this.b;			
		} else if(ch=='c'){
			result = this.c;
		} else if(ch=='d'){
			result = this.d;
		}else {
			System.out.println("없는 행렬을 골랐습니다.");
		}
		
		return result;
	}

 

4. chooseArray()

콘솔에서 입력한 문자를 받아서 배열로 만드는 메서드이다.

배열로 받아서 나중에 위의 findArray(char ch) 함수의 매개변수로 각 요소를 넣으면

문자 배열 안에 있는 문자에 맞게 각 배열이 선택될 것이다.

 

일단 이것은 배열을 받을 때 일종의 유효값 검사에 해당한다고 볼 수 있다

멤버변수로 선언한 배열이 a b c d 뿐이므로 그것이 아닌 다른 문자를 넣지 못하도록 한 것이다.

받은 글자들이 abcd중에 있다면 문자열에 추가하고 그렇지 않으면 안된다고 한다.

반복문을 써서 사용자가 원할 때 입력을 멈출 수 있다.

 

다 받은 문자열을 chatAt함수로 배열에 넣어 반환한다.

char[] chooseArray() {
		
		char[] result;
		String choice = "";
		
		while (true) {
			String tmp = scanner.nextLine();
			  
			if(tmp.equals("q")) {
				break;
			} else if(tmp.equals("a") | tmp.equals("b") | tmp.equals("c") | tmp.equals("d")) {
				choice += tmp;
			} else {	
				System.out.println("사용할 수 없는 행렬입니다.");
				continue;
			}
		}
		System.out.println(choice);
		result = new char[choice.length()];

		for(int i = 0; i < result.length; i++) {
			result[i] = choice.charAt(i);
		}
		return result;
	}

 

5. mulArrayDouble(int [][] a, int [][] b)

두 행렬일 때 곱하기 이다.

fot 안의 반복자를 어떻게 사용했는지 잘 보기 바란다.

행렬 포스팅을 참고하면 이해가 쉬울 듯 하다.

포인트는 앞 행렬의 행이 바뀌는 것과 뒷 행렬의 열이 바뀌는 것을 잘 포함 시키는 것이고

또 앞 행렬의 행과 뒷 행렬의 열이 곱해지는데 그 인덱스가 같다는 것이다.

 

또한 앞 행렬의 열과 뒷 행렬의 행의 크기가 같아야 곱할 수 있으므로 조건문으로 검사해줬다.

int[][] mulArrayDouble(int [][] a, int [][] b){
		
		int [][] result = new int[a.length][b[0].length];
		
		if(a[0].length == b.length) {
			for(int h=0;h<a.length;h++)	{ 
				for(int i=0;i<b[h].length;i++) {
					int tmp = 0;
					for(int j=0;j<b.length;j++) {
						tmp += a[h][j]*b[j][i];
					}
					result[h][i] = tmp;
				}
			}
		}else {
			System.out.println("행렬을 곱할 수 없는 순서 입니다. 다시 입력해 주세요.");
		}
		return result;
	}

 

6. mulArrayTriple(int [][] a, int [][] b, int [][] c)

세 행렬이다.

위에서 언급했드시 어떻게 곱하느냐에 따라 속도 차이가 난다.

더 적게 곱할 수 있도록 고안해서

위의 mulArrayDouble(int [][] a, int [][] b)을 이용해 곱해줬다.

다음에는 한 메서드를 제귀호출 할 수 있도록 구현해 보겠다.

int [][] mulArrayTriple(int [][] a, int [][] b, int [][] c){
		int [][] result = new int[a.length][b[0].length];
		
		if(a.length >= c[0].length) {
			result = mulArrayDouble(a,mulArrayDouble(b,c));
		}else {
			result = mulArrayDouble(mulArrayDouble(a,b),c);
		}
		return result;
	}

 

7. showQuestion() 

문제 보는게 길어서 따로 메서드로 뽑았다.

void showQuestion() {
		System.out.println("행렬 a");
		showArray(a);
		
		System.out.println();
		System.out.println("행렬 b");
		showArray(b);	
		
		System.out.println();
		System.out.println("행렬 c");
		showArray(c);
		
		System.out.println();
		System.out.println("행렬 d");
		showArray(d);
		
		System.out.println();
		System.out.println("곱할 행렬을 쓰세요. 완료 : q");
	}
	

 

8. main()

콘솔로 입력받은 문자들을 배열로 만들어서

그 배열의 길이가 얼마냐에 따라 실행하는 곱셈 메서드가 달라진다.

배열 길이가 2 면 mulArrayDouble(int [][] a, int [][] b)메서드를

배열 길이가 3 면 mulArrayTriple(int [][] a, int [][] b, int [][] c)메서드를 호출하며

각 메서드 호출 시 매개변수로 넣는 배열들은

findArray(char ch)에 배열 요소들을 넣어서 구현했다.

public static void main(String[] args) {
		MarrayPrac_matrixMul mm = new MarrayPrac_matrixMul();
				
		question : while(true) {
			
			mm.showQuestion();
			
			char[]  matrixArr = mm.chooseArray();
			
			if(matrixArr.length <= 0) 
				continue;
			
			switch (matrixArr.length) {
			case 1 : 
				System.out.println("곱할 것이 없습니다."); 
				break;
			case 2 : 
				System.err.println("결과 : ");
				mm.showArray(mm.mulArrayDouble(mm.findArray(matrixArr[0]), mm.findArray(matrixArr[1])));
				break;
			case 3 : 
				System.err.println("결과 : ");
				mm.showArray(mm.mulArrayTriple(mm.findArray(matrixArr[0]), mm.findArray(matrixArr[1]), mm.findArray(matrixArr[2])));
				break;	
	
			default:
				break question;
			}

			System.out.println("더 곱하시겠습니까? y/n");

			if(mm.scanner.nextLine().equals("y"))
				continue;
			else if(mm.scanner.nextLine().equals("n")){
				break question;
			} else {
				System.out.println("잘못 누르셨습니다. 다시 선택하세요.");
				continue;
			}
		}	
		mm.scanner.close();		
		return;
	}

 

9. 전체 코드

public class MarrayPrac_matrixMul {
/* 행렬의 곱셈
 * 두 행렬을 곱한 결과를 출력
 * 
 * 행렬의 곱셈은 앞 행렬의 열과 뒤 행렬의 헹의 크기가 같아야 가능
 * m(a,b) n(b,r) 
 * 곱할 행렬이 많을 경우 행렬을 곱하는 순서(결합법칙)에 따라 속도가 달라지므로 
 * 가능한 행렬 크기가 작은 방향으로 곱하게 해야 함
 * 셋 중 가장 큰 행과 열의 크기가 뭔지 찾아보자
 * 
 */

	Scanner scanner = new Scanner(System.in);

	int [][] a = {{4, 4, 5}, {3, 7, 2}}; // 2, 3
	int [][] b = {{7, 5, 1, 2}, {9, 6, 4, 3}, {4, 2, 1, 6}}; // 3, 4
	int [][] c = {{8, 4}, {5, 7}, {2, 3}, {9, 6}}; // 4, 2
	int [][] d = {{1, 4}, {9, 3}, {7, 6}}; // 3, 2
	
	// a * b , b * c , c * a
	
	int[][] mulArrayDouble(int [][] a, int [][] b){
		
		int [][] result = new int[a.length][b[0].length];
		
		if(a[0].length == b.length) {
			for(int h=0;h<a.length;h++)	{ 
				for(int i=0;i<b[h].length;i++) {
					int tmp = 0;
					for(int j=0;j<b.length;j++) {
						tmp += a[h][j]*b[j][i];
					}
					result[h][i] = tmp;
				}
			}
		}else {
			System.out.println("행렬을 곱할 수 없는 순서 입니다. 다시 입력해 주세요.");
		}
		return result;
	}
	
	int [][] mulArrayTriple(int [][] a, int [][] b, int [][] c){
		int [][] result = new int[a.length][b[0].length];
		
		if(a.length >= c[0].length) {
			result = mulArrayDouble(a,mulArrayDouble(b,c));
		}else {
			result = mulArrayDouble(mulArrayDouble(a,b),c);
		}
		return result;
	}
	
	int [][] findArray(char ch) {

		int [][] result = null;
		
		if(ch=='a'){
			result = this.a;			
		} else if(ch=='b'){
			result = this.b;			
		} else if(ch=='c'){
			result = this.c;
		} else if(ch=='d'){
			result = this.d;
		}else {
			System.out.println("없는 행렬을 골랐습니다.");
		}
		
		return result;
	}
	
	void showArray(int[][] a) {
		for(int[] col : a) {
			for(int tmp : col) {
				System.out.print(tmp+" ");
			}
			System.out.println();
		}
		System.out.println();
	}
	
	void showQuestion() {
		System.out.println("행렬 a");
		showArray(a);
		
		System.out.println();
		System.out.println("행렬 b");
		showArray(b);	
		
		System.out.println();
		System.out.println("행렬 c");
		showArray(c);
		
		System.out.println();
		System.out.println("행렬 d");
		showArray(d);
		
		System.out.println();
		System.out.println("곱할 행렬을 쓰세요. 완료 : q");
	}
	
	char[] chooseArray() {
		
		char[] result;
		String choice = "";
		
		while (true) {
			String tmp = scanner.nextLine();
			  
			if(tmp.equals("q")) {
				break;
			} else if(tmp.equals("a") | tmp.equals("b") | tmp.equals("c") | tmp.equals("d")) {
				choice += tmp;
			} else {	
				System.out.println("사용할 수 없는 행렬입니다.");
				continue;
			}
		}
		System.out.println(choice);
		result = new char[choice.length()];

		for(int i = 0; i < result.length; i++) {
			result[i] = choice.charAt(i);
		}
		return result;
	}
	
	public static void main(String[] args) {
		MarrayPrac_matrixMul mm = new MarrayPrac_matrixMul();
				
		question : while(true) {
			
			mm.showQuestion();
			
			char[]  matrixArr = mm.chooseArray();
			
			if(matrixArr.length <= 0) 
				continue;
			
			switch (matrixArr.length) {
			case 1 : 
				System.out.println("곱할 것이 없습니다."); 
				break;
			case 2 : 
				System.err.println("결과 : ");
				mm.showArray(mm.mulArrayDouble(mm.findArray(matrixArr[0]), mm.findArray(matrixArr[1])));
				break;
			case 3 : 
				System.err.println("결과 : ");
				mm.showArray(mm.mulArrayTriple(mm.findArray(matrixArr[0]), mm.findArray(matrixArr[1]), mm.findArray(matrixArr[2])));
				break;	
	
			default:
				break question;
			}

			System.out.println("더 곱하시겠습니까? y/n");

			if(mm.scanner.nextLine().equals("y"))
				continue;
			else if(mm.scanner.nextLine().equals("n")){
				break question;
			} else {
				System.out.println("잘못 누르셨습니다. 다시 선택하세요.");
				continue;
			}
		}	
		mm.scanner.close();		
		return;
	}
}

 

결과

 

 

1. char[][] board;

클래스 내의 멤버들이 접근 가능한 멤버변수 배열 char[][] board를 선언한다.

 

2. makeBoard(int size) 

모든 항목이 0으로 초기화된 배열을 만든다.

매개변수로 배열 크기를 전달받아 그 크기만큼 배열을 만들 것이다.

char[][] makeBoard(int size) {
	
		board = new char[size][size];
		
		for(int i = 0; i<size; i++){
			for(int j = 0; j<size; j++) {
				board[i][j]= 'O'; 
			}
		}
		return board;
	}

 

3.  showArray(char[][] a)

배열의 결과를 출력하는 메서드를 만들었다.

void showArray(char[][] a) {
		for(char[] col : a) {
			for(char tmp : col) {
				System.out.print(tmp+" ");
			}
			System.out.println();
		}
	}

 

4. char[][] markBoard(int x, int y) {

인수를 전달 받아 해당 위치의 배열 요소를 X로 바꾼다. 

char[][] markBoard(int x, int y) {
		
		board[x-1][y-1] = 'X';
		
		return board;
	}

 

5. main( )

먼저 5*5 배열을 만든다.

콘솔에서 좌표값을 받아 표시한다.

public static void main(String[] args) {
		MarrayPrac_pointX mp = new MarrayPrac_pointX();
		mp.board = mp.makeBoard(5);
		mp.showArray(mp.board);
		
		System.out.println("원하는 위치의 좌표를 입력하시오.");
		Scanner scanner = new Scanner(System.in);
		System.out.println("x : ");
		int x = scanner.nextInt();
		System.out.println("y : ");
		int y = scanner.nextInt();
		
		scanner.close();
		
		mp.showArray(mp.markBoard(x, y));
		
	}

 

6. 전체 코드

public class MarrayPrac_pointX {
/* 좌표에 X표 하기
 * 입력한 2차원 좌표의 위치에 X 놓기
 */
	char[][] board;
		
	char[][] makeBoard(int size) {
	
		board = new char[size][size];
		
		for(int i = 0; i<size; i++){
			for(int j = 0; j<size; j++) {
				board[i][j]= 'O'; 
			}
		}
		return board;
	}
	
	void showArray(char[][] a) {
		for(char[] col : a) {
			for(char tmp : col) {
				System.out.print(tmp+" ");
			}
			System.out.println();
		}
	}
	
	char[][] markBoard(int x, int y) {
		
		board[x-1][y-1] = 'X';
		
		return board;
	}
	
	public static void main(String[] args) {
		MarrayPrac_pointX mp = new MarrayPrac_pointX();
		mp.board = mp.makeBoard(5);
		mp.showArray(mp.board);
		
		System.out.println("원하는 위치의 좌표를 입력하시오.");
		Scanner scanner = new Scanner(System.in);
		System.out.println("x : ");
		int x = scanner.nextInt();
		System.out.println("y : ");
		int y = scanner.nextInt();
		
		scanner.close();
		
		mp.showArray(mp.markBoard(x, y));
		
	}
}

 

결과

+ Recent posts