함수 3, 클래스와 객체, 외부 라이브러리 사용
아래 모든 문제에 적용되는 지시 사항
- 클래스 선언문 바로 위에 그 클래스에 대한 설명을 주석으로 넣으시오.
- main 함수 외의 함수에도 주석을 넣으시오.
- 주석의 첫 부분은 /** 로 시작하고 끝 부분은 */로 마칩니다.
- 주석을 적어 넣지 않거나 들여쓰기를 하지 않으면 감점합니다.
P1 (클래스 선언과 객체 활용)
강의자료에 나오는 Cat과 Test 등 두 개의 클래스로 이루어진 애플리케이션을 작성하고 실행해 보시오. week7 패키지에 Cat.java, Test.java 등 두 개의 파일을 만들고 main 메소드를 갖고 있는 Test 클래스를 실행시키면 됩니다.
P2 (String 클래스 활용)
강의자료 끝 부분에 있는 StringTest 클래스를 잘 읽어보고 이 프로그램과 비슷한 프로그램을 작성하시오. “A barking dog” 대신 한글로 된 임의의 문자열을 놓고 아래와 같은 String메소드를 호출하고 결과를 보이도록 하시오. 아래 메소드 사용법은 자바 api 문서나 인터넷 검색을 통해 (구글 검색에서 “자바 String 클래스”를 키워드로 하여 검색) 알 수 있습니다. 클래스 이름은 StringTest로 지으시오.
length
concat
substring
indexOf
charAt
replace
아래는 프로그램 출력 예입니다. 출력은 학생마다 다를 것입니다.
P3 (String 클래스 활용)
지난 주에 정수를 이루는 각 숫자를 하나씩 차례로 출력하는 프로그램을 작성했습니다. 그 때는 십진수의 원리를 이용하여 각 자릿수를 분리하는 방법을 사용했습니다. 이번에는 사용자가 임의의 숫자를 입력하면 이것을 String타입으로 읽어 들이고, 이 String에 적절한 메소드를 호출함으로써 각 자릿수와 소수점 부호, 마이너스 기호를 분리하여 출력하도록 프로그램을 작성합니다. 클래스 이름은 Digits로 지으시오. 출력은 아래 그림과 같습니다.
[힌트]
String 클래스의 charAt 메소드를 이용하면 간단히 문제를 풀 수 있습니다.
P4 (객체 생성, 외부라이브러리 이용)
우리는 프로그래밍을 처음 시작할 때 컴퓨터에 자바를 설치했습니다. 더 정확히는 자바 JDK(Java Development Kit)를 설치했습니다. JDK에는 자바표준라이브러리(자주 사용되는 많은 클래스들로 구성됨)가 포함되어 있습니다. 우리가 지금까지 사용한 String, Scanner, System 등의 클래스들은 모두 이 자바표준라이브러리에 들어 있는 클래스들이었습니다. 라이브러리란 남들이 만들어 놓은 유용한 프로그램들의 꾸러미입니다.
이번 시간에는 이 표준라이브러리에 들어 있는 클래스가 아닌 외부 라이브러리 클래스를 사용합니다. 그러기 위해서 그 클래스들이 포함된 추가적인 라이브러리를 이클립스에 넣어줄 것입니다. (누구나 클래스를 작성한 후 그 클래스를 일종의 라이브러리로 공개하고 다른 이들이 그 라이브러리를 사용하게 할 수 있습니다.)
[환경 설정]
아래 절차에 맞춰 외부 라이브러리를 내 프로젝트에 설치하는 작업을 하시오.
① stdlib.package.jar 파일을 다운로드하여 적당한 폴더에 저장한다. 압축은 풀지 않는다.
② Eclipse에서 프로젝트 이름을 오른쪽 버튼 클릭 - Properties 선택하여 열리는 대화창에서 Java Build Path를 선택하고, 가운데 부분에서 Libraries 탭을 선택한다. 오른쪽 부분에 있는 Add External JARs… 선택. – ①에서 저장한 폴더를 찾아 stdlib-package.jar를 선택하고 “Apply and Colse”” 버튼 클릭.
프로젝트 폴더에 아래 그림과 같이 라이브러리가 나타나면 된다.
③ Turtle.java 파일을 eclipse 프로젝트의 week7 패키지에 복사해 넣는다. Turtle 클래스에 문법 오류가 있다는 의미로 빨간 x 표시가 몇 군데 나타난다. 프로그램 코드 왼쪽에 나타난 빨간 x표 중 하나를 클릭한다. 그러면 이 에러의 해결책들이 나타난다. 그 중 첫번째 것을 더블클릭한다.
그러면, 아래와 같이 추가로 설치한 라이브러리에 들어 있는 StdDraw 클래스가 import된다.
맨 위에 있는 파일 이름 앞의 * 표시는 아직 저장되지 않은 변경 사항이 있다는 의미이다.
control-s를 누르면 저장이 되면서 *표시가 없어지고 빨간 x표시도 없어진다.
④ TurtleDrive.java 파일을 eclipse 프로젝트의 week7 패키지에 복사해 넣는다.
TurtleDrive.java 파일이 활성화된 상태에서 실행 버튼을 클릭하여 실행한다.
⑤ TurtleDrive.java 파일을 잘 읽어보고 Turtle 클래스를 어떻게 사용하는지 익힌다.
아래 지시에 따라 프로그램을 작성하시오.
TurtleDrive 클래스를 복사하여 TurtleDrive1 클래스를 만들고 TurtleDrive1의 main 메소드를 아래 지시에 따라 수정하시오.
- TurtleDrive의 main에서는 사각형의 네 선분을 그리기 위해 같은 코드를 네 번 반복해서 적어주었습니다.
- TurtleDrive1의 main에서는 사각형의 네 선분을 그리기 위해 반복문을 사용함으로써 같은 코드가 네 번 반복되지 않도록 하시오. 단, Turtle 인스턴스를 여러 개 만들지 말고 하나의 Turtle을 움직여 그림을 그리시오.
- main 메소드의 34번 줄에 불필요해 보이는 문장이 있습니다(아래 그림).
논리적으로는 이 문장이 필요 없습니다. 그러나 이 문장을 생략하면 마지막 선분이 그려지지 않습니다. 아마도 우리가 가져다가 사용하고 있는 라이브러리 소프트웨어에 약간의 문제가 있는 것 같습니다. 아래 문제를 풀 때도 맨 마지막에 이 문장을 넣어 주어야 합니다.
- 그림을 그리는 프로그램을 실행하면 새 창이 열리고 그 곳에 그림이 그려집니다. 그리고 이클립스 콘솔창을 보면 아래 그림처럼 빨간 색 네모 버튼이 나타납니다.
이 버튼이 빨간색일 때는 프로그램이 아직 종료되지 않고 실행 중이라는 의미입니다. 이 버튼을 클릭하면 실행 중인 프로그램이 강제로 종료됩니다.
그림이 그려진 창의 모서리에 있는 x 버튼을 눌러 창을 닫으면 프로그램이 종료됩니다.
P5
아래 지시에 따라 프로그램을 작성하시오.
TurtleDrive1 클래스를 복사하여 TurtleDrive2 클래스를 만들고 TurtleDrive2의 main 메소드를 아래 지시에 따라 수정하시오.
- TurtleDrive1의 main에서는 사각형을 그렸습니다. TurtleDrive2의 main에서는 오각형을 그리도록 하시오. (한 번 꺽을 때 몇 도나 꺽으면 될까요?
- Main 메소드의 마지막에 아래 문장을 넣으시오. 라이브러리 클래스의 버그 때문에 이 문장이 들어가야 합니다.
turtle.pause(1000);
P6
아래 지시에 따라 프로그램을 작성하시오.
아래와 같은 그림을 그리게 하시오. 클래스 이름은 TurtleDrive3로 하시오. 단, Turtle 인스턴스를 여러 개 만들지 마시오. 하나의 Turtle을 움직여 그림을 그리시오.
P7
아래 지시에 따라 프로그램을 작성하시오.
위 P6와 같은 그림을 그리되 사각형을 한 개 그리는 메소드를 구현하고 그 메소드를 이용하여 그림을 그리도록 하시오. 메소드 이름은 drawSquare로 지으시오. 클래스 이름은 TurtleDrive4로 하시오. 아래 뼈대를 참고하시오.
[참고]
- 메소드에 객체를 넘겨줄 수 있습니다.
- 메소드에 객체를 넘겨준다는 말은 객체를 가리는 참조를 넘겨준다는 말입니다. 아래 그림을 보세요.
위 그림의 main 메소드 내에서 거북이에게 0.5만큼 앞으로 가도록 지시하려면 아래와 같이 적으면 된다.
turtle.goForward(0.5);
위 그림의 drawSquare 메소드 내에서 거북이에게 0.5만큼 앞으로 가도록 지시하려면 아래와 같이 적으면 된다.
t.goForward(0.5);
P8
아래 지시에 따라 프로그램을 작성하시오.
클래스 이름은 TurtleDrive5로 지으시오.
아래 그림을 참고하여 정다각형을 그리는 메소드를 구현하시오. 메소드 이름은 drawNgon으로 지으시오.
main에서 drawNgon 메소드를 호출하여 P6와 같은 네 개의 정사각형을 그리게 해 보시오. 사용자 입력에 따라 자유롭게 도형을 그리지 않고 고정적으로 4각형을 네 개 그리도록 해도 됩니다.
P9 아래 지시에 따라 프로그램을 작성하시오.
TurtleDrive5를 복사하여 TurtleDrive6을 만드시오.
main 메소드에서 drawNgon 메소드를 (세 번) 호출하여 아래와 같이 세 개의 사각형을 그리도록 하시오.
P10
아래 지시에 따라 프로그램을 작성하시오.
TurtleDrive6를 복사하여 TurtleDrive7를 만드시오. main 메소드에서 drawNgon 메소드를 (세 번) 호출하여 아래와 같이 세 개의 삼각형을 그리도록 하시오.
P11
아래 지시에 따라 프로그램을 작성하시오.
TurtleDrive7을 복사하여 TurtleDrive8을 만드시오. main 메소드에서 몇각형을 몇 개나 그릴 것인지 임의로 설정할 수 있게 하시오. 아래 그림을 참고하시오.
예를 들어, 정사각형을 여섯 개 그리도록 하면 (N = 4, HOW_MANY = 6), 아래와 같은 그림이 그려집니다.
- drawNgon 메소드에서 선분 그리기 사이 사이의 잠시멈춤 시간을 1000ms에서 100ms로 변경하시오. TurtleDrive8클래스의 main에서 HOW_MANY를 30으로하고 N을 3, 4, 5로 바꿔가면서 실행해 보시오.
[보충문제] 이 문제는 풀지 않아도 되며 과제 결과로 제출하지 않습니다.
양수의 제곱근을 구하는 프로그램을 작성하시오.
양수 c의 제곱근(를 구하는 법
임의로 찍은 초기 근사값을 이라고 하자. 참값은
이다.
만약 라면, (양변의 역수를 취하면)
이므로, (양변에 c를 곱하면)
이다.
그리고, 과
의 산술평균인
는
보다 참값에 가깝다.
이 산술평균 값을 새로운 근사값 으로 삼고 위 과정을 다시 수행한다.
n번째 근사값이 일 때, n+1번째 근사값
은 아래 식으로 구한다.
이렇게 반복하면 t가 점점 참값 로 근접해간다. (
보다 큰 쪽에서
로 수렴한다.)
은 어떤 양수로 설정해도 된다. 통상 c로 설정한다.
많은 경우 가 무리수이다. 가령
는 무리수이다. 이런 경우 아무리 많이 반복하더라도 참값에 정확히 도달할 수는 없다. 가까워질 뿐이다. 그러므로 “어느 정도 참값에 접근하면” 계산을 중단하고 그 때의 근사값을 취한다.
계산을 반복할수록 과
사이의 거리가 작아지므로 이 거리가 어떤 정해진 기준 이내로 작아질 때 중단하게 하면 될 것이다. 허용 오차를 epsilon이라고 하자.
double epsilon = 1.0e-15; // 허용 오차.
그리고, 아래 조건이 만족되는 동안만 계산을 반복하면 된다.
Math.abs(t - c/t) > epsilon*t
Math.abs( )는 절대값을 구하는 함수이다. 괄호 안에 있는 표현식의 절대값을 구해준다. 그러니까, Math.abs(-5.3)은 5.3이고, Math.abs(5.3)도 5.3이다. Math.abs(t - c/t)는 와
사이의 거리이다.
가 작을 때는 허용 오차도 작아야 하고
가 클 때는 그에 맞춰 허용 오차도 크게 설정하는 것이 자연스럽다. 참값이 1000.0일 때는 0.0001의 오차가 작은 오차이지만, 참값이 0.01이라면 0.0001의 오차는 매우 큰 오차이다.) 그래서 허용 기준을 eplison이 아닌 epsilon*t로 설정한다. (참값
는 알지 못하므로 근사값인 t를 곱한다.)
import java.util.Scanner;
/**
* 0보다 큰 소수의 제곱근(square root)을 구한다.
*/
public class SquareRoot {
public static void main(String[] args) {
System.out.print("0보다 큰 수 하나를 입력하시오: ");
Scanner input = new Scanner(System.in);
double c = input.nextDouble();
// 만약 자판에서 int 타입 값 10을 입력하면 10.0이 읽힌다.
// (자동형변환: 작은 타입 값이 큰 그릇으로 들어갈 때).
double epsilon = 1.0e-15; // 허용 오차.
double t = c; // c의 제곱근의 근사값.
// Newton update step을 반복적으로 실행한다.
// 바라는 정밀도에 도달할 때까지...
while (Math.abs(t - c/t) > epsilon*t) {
// 코드를 추가할 곳.
System.out.println(t);
}
input.close();
}
}
끝.