프로그래밍기초 제4주 실습과제

       

조건문과 반복문 3

       

P1~P11 까지 하나의 zip파일로 만들어 학번_이름.zip 으로 이름을 저장하여 제출하면 됩니다.

  • 제출은 알집이 아닌 zip파일로 저장하여 보내주세요.

프로그램을 작성할 때는 아래에 있는 관례를 지켜야 합니다.

  1. 클래스 이름은 영어 대문자로 시작 (School, Power)
  2. 변수이름은 소문자로 시작 (accountNo, initialValue)
  3. 변수의 이름을 정할 때에는 의미 있는 이름을 지어야 한다.
  4. 낙타표기법 (numberOfWords, isTheBest)
  5. 논리적 들여쓰기(indentation)을 해야 합니다. 프로그램을 편집하면서 중간중간에 control-a, control-i를 눌러 들여쓰기를 맞추세요.

아래 모든 문제에 적용되는 지시 사항

  1. 클래스 선언문 바로 위에 그 클래스에 대한 설명을 주석으로 넣으시오.
  2. 주석의 첫 부분은 /** 로 시작하고 끝 부분은 */ 로 마칩니다.

아래 그림에 예를 보입니다.

이 주석을 적어 넣지 않거나 주석의 내용이 부실한 경우 감점합니다.

img


img


img


       

P1 (while 문장, 자동 형변환)

키보드로부터 양수들을 받아들여 이 수들의 평균을 구해 소수점 두 자리까지 출력하는 프로그램을 작성하시오. 클래스 이름은 Average로 지으시오. 사용자는 정수를 입력할 수도 있고 소수를 입력할 수도 있어야 합니다. 양수가 하나도 입력되지 않은 경우에는 그에 맞는 적절한 출력을 보여주어야 합니다.

실행화면은 아래와 같습니다.

img

img

img

img

힌트

  • 프로그램은 정수와 소수를 모두 읽어 들일 수 있어야 한다. double 타입이 int 타입보다 큰 그릇이므로 double 타입 변수를 선언하고 이 곳에 사용자 입력 값을 저장하면 소수도 저장할 수 있고 정수도 저장할 수 있다. (int 타입 변수를 선언하면 double 타입 값은 저장하지 못한다.)

  • 키보드로부터 값을 읽어 들이기 위해 input.nextDouble() 을 사용하는 경우, 사용자가 정수를 입력하면 그 정수가 double 타입으로 자동 형변환되어 읽혀진다. input.nextInt() 를 사용하는 경우, 사용자가 소수를 입력하면 에러가 발생한다.

  • 사용자가 입력하는 값을 차례로 읽어 누적합을 구해 저장해 둘 변수가 필요하다. double 타입 값을 누적해 더한 값을 저장할 변수이므로 이것 역시 double 타입으로 선언한다. 가령 double sum.

  • 어떤 조건이 만족되는 때만, 즉 사용자 입력이 양수인 때만 누적합을 구하는 작업을 반복해야 하므로 while 문장을 사용한다.

  • while 문장 다음에, 평균을 구해 결과를 화면에 출력하는 문장(들)이 있어야 한다.

       

P2 (switch 문장)

사칙연산을 하는 프로그램을 작성하시오. 사용자가 정수를 입력하건 소수를 입력하건 언제나 소수 계산을 하도록 하시오. 클래스 이름은 Calculator로 하시오.

실행화면은 아래와 같습니다.

img

img

네 가지 연산자 외의 다른 문자가 입력되는 경우 적절한 안내 메세지를 출력하고 프로그램이 종료되게 하시오.

아래 그림과 같이 Switch 문장을 사용하면 됩니다. System.exit(-1)은 프로그램이 즉시 종료되게 합니다.

img

참고

아래 문장은 따옴표로 둘러싸인 문자열을 출력합니다.

System.out.printf("%c=%d", A, 65);

출력할 문자열 안에는 %로 시작하는 형식지정자가 두 개 있습니다. 형식지정자 두 개는 %c, %d 입니다. ‘A’는 첫 형식지정자 위치에, 65는 두 번째 형식지정자 위치에 들어갑니다. char 타입 한 글자를 출력할 때는 형식지정자 %c를 사용합니다. 정수를 출력하고자 할 때는 형식지정자 %d를 사용합니다. String을 출력하고자 할 때는 형식지정자 %s를 사용합니다. 위 문장의 출력은 아래와 같습니다.

img

System.out.printf("%s = %d", "A의 아스키코드", 65);

위 문장의 출력은 아래와 같습니다.

A의 아스키코드 = 65

       

P3 (이중 반복문)

아래 그림과 같은 삼각형 그림을 그리는 프로그램을 작성하시오. 삼각형의 크기는 사용자가 키보드 입력으로 지정하게 하시오. 클래스 이름은 Triangle로 지으시오.

실행화면은 아래와 같습니다.

img

힌트

아래와 같은 그림을 그리기 위해서는

img

  • 제 1줄을 출력하기 위해: *를 출력하는 작업을 3회 반복한다.

  • 다음 줄로 내려간다.

  • 제 2줄을 출력하기 위해: *를 출력하는 작업을 3회 반복한다.

  • 다음 줄로 내려간다.

  • 제 3줄을 출력하기 위해: *를 출력하는 작업을 3회 반복한다.

  • 다음 줄로 내려간다.

  • 제 4줄을 출력하기 위해: *를 출력하는 작업을 3회 반복한다.

  • 다음 줄로 내려간다.

이것을 프로그램 코드로 작성하면 아래와 같이 된다.

img

문제에 주어진 그림을 그리기 위해서는 아래와 같이 실행하면 된다.

  • 제 1줄을 출력하기 위해: *를 출력하는 작업을 1회 반복한다.

  • 제 2줄을 출력하기 위해: *를 출력하는 작업을 2회 반복한다.

  • 제 3줄을 출력하기 위해: *를 출력하는 작업을 3회 반복한다.

  • 제 n줄을 출력하기 위해: *를 출력하는 작업을 n회 반복한다.

       

P4 (for 문장 안의 for 문장)

아래 그림과 같은 삼각형 그림을 그리는 프로그램을 작성하시오. 삼각형의 크기는 사용자가 키보드 입력으로 지정하게 하시오. 클래스 이름은 ReversedTriangle로 지으시오.

실행화면은 아래와 같습니다.

img

       

P5 (if 문장)

키보드로부터 정수 세 개를 입력 받아 이들을 오름차순으로 출력하는 프로그램을 작성하시오. 클래스 이름은 Sorter로 지으시오.

실행화면은 아래와 같습니다.

img

img

img

힌트:

  • 우선 세 숫자를 읽어 변수 i, j, k에 저장한다.

  • i, j, k에 어떤 숫자가 들어가게 될지 프로그래머는 사전 알 수 없다.

  • i, j, k를 상호 비교할 때는 두 개씩만 비교할 수 있다. (>, >=, <, <=, == 등 관계연산자는 이항연산자임.)

  • (1) i, j, k에 들어 있는 값을 그대로 둔 채 i, j, k 중 작은 것부터 큰 것 순으로 출력할 수도 있고, (2) i, j, k의 값이 오름차순이 되도록 i, j, k 값을 서로 맞바꾼 후, i, j, k를 차례로 출력할 수도 있다.

방법 (1)

 if (i가 가장 작은가?)
      if (j < k)
       	   //i, j, k 순으로 출력한다
       else
           //i, k, j 순으로 출력한다.
 else if (j가 가장 작은가?)
       if (i < k)
           //j, i, k 순으로 출력한다.
       else
           // j, k, i 순으로 출력한다.
 else  // k가 가장 작은 경우
      if (i < j)
          //k, i, j 순으로 출력한다.
      else
          //k, j, i 순으로 출력한다.

방법 (2)

  1. i, j, k의 값이 오름차순이 되도록 값을 맞바꾼다.

  2. i > j이면 i와 j의 값을 맞바꾼다.

  3. i > k이면 i와 k의 값을 맞바꾼다. 이렇게 하고 나면 i에 가장 작은 값(혹은 같은 값)이 들어 있게 된다.

  4. j > k이면 j와 k 값을 맞바꾼다. 이렇게 하면 나면 j에 k보다 같거나 작은 값이 들어 있게 된다.

  5. i, j, k를 차례로 출력한다.

       

P6 (if 문장)

소득이 있는 곳에 세금이 있습니다. 소득에 대해 매기는 세금을 소득세라고 합니다. 소득세에는 누진제가 적용됩니다. 즉 소득이 적으면 세금을 적게 내고 (세율이 낮고) 소득이 많으면 세금을 많이 냅니다(세율이 높습니다). 소득에 따른 세율이 아래와 같다고 합시다.

연소득(원) 세율(%)
4600만원 이하 15.0
8800만원 이하 24.0
8800만원 초과 35.0

일년에 8800만원을 버는 사람의 경우 8800만원 전체에 대해 24.0%의 세율을 적용하면 세금(소득세)이 2112만원이 되고(8800 x 0.24 = 2112), 총소득에서 소득세를 빼고 난 세 후의 순소득은 8800만원 - 2112만원 = 6688만원이 됩니다.

일년에 9000만원을 버는 사람의 경우 9000만원 전체에 대해 35.0%의 세율을 적용하면 세금이 3150만원이 되고(9000 x .35 = 3150), 총소득에서 소득세를 빼고 난 세 후 순소득은 9000만원 - 3150만원 = 5850만원이 됩니다.

그러니까 총소득 9000만원인 사람이 총소득 8800만원인 사람보다 오히려 순소득(세금을 내고 난 후의 소득)이 작아집니다. 이렇게 되면 안 되겠지요. 사람들이 8800만원을 벌게 되면 더 이상 벌려고 하지 않을 것이고 노동 의욕을 잃어버릴 테니까요.

그러니까 실제로는 위와 같이 세금을 매기지 않고 이렇게 세금을 계산합니다. 9000만원을 번 사람의 경우 9000만원 중 처음 4600만원에 대해서는 15.0%의 세율을 적용하고, 그 다음 4600만원 초과, 8800만원 이하인 4200만원에 대해서는 24.0%의 세율을 적용합니다. 그리고 8800만원을 초과하는 200만원에 대해서만 35.0%의 세율을 적용합니다.

그러니까 9000만원 소득자의 소득세는 아래와 같이 계산됩니다.

4600만 * 15.0/100.0 + (8800만 - 4600만) * 24.0/100.0 + (9000만 - 8800만) * 35.0/100.0 = 1768만원

소득을 입력하면 소득세를 알려주는 프로그램을 작성하시오. 소득 금액은 음수가 아니라고 가정하시오. 클래스 이름은 TaxCalculator로 지으시오.

참고:

세율은 고정된 숫자, 즉 상수이므로 아래와 같이 선언합니다. 상수의 이름은 모두 대문자로 짓습니다.

final double TAX_RATE_LOW = 15.0/100.0;
final double TAX_RATE_MID = 24.0/100.0;
final double TAX_RATE_HIGH = 35.0/100.0;

실행화면은 아래와 같습니다.

img

img

img

img

       

P7 (for 문장: 거듭제곱 구하기)

2의 거듭제곱수들을 구하는 프로그램을 작성하시오. 클래스 이름은 Powers로 지으시오. 실행 화면은 아래와 같습니다. 사용자는 항상 0 이상 정수만을 입력한다고 가정합니다.

img

img

img

코드에서 int 타입 변수를 사용하는 경우, 숫자가 너무 커지면 계산 결과를 int 타입 변수에 저장할 수 없게 되어 올바르지 않은 결과를 출력하게 됩니다. 얼마를 입력하면 결과가 틀려지는지 관찰해보시오.

참고

영어로 거듭제곱을 어떻게 읽는가?

img

       

P8

주어진 수보다 작거나 같은 2의 거듭제곱수들 중 가장 큰 수를 구하는 프로그램을 작성하시오. 주어진 수는 자연수라고 가정합니다. 아래 그림을 참고하시오.

img

실행 예는 아래와 같습니다.

img

img

img

img

       

P9

10진수를 2진수로 변환하는 프로그램을 작성하시오. 클래스 이름은 Dec2Bin으로 지으시오. 실행 예는 아래와 같습니다. 사용자는 자연수만을 입력한다고 가정합니다.

img

img

img

img

img

힌트

아래 표는 십진수를 2진수로 변환하는 과정을 보여줍니다.

img

첫 예로 13을 이진수로 변환하는 과정을 봅시다.

13 = 8+4+1 = 23+22+20 = 1x23+1x22+0x21+1x20 이므로 이진수로 표현하면 1101이 됩니다.

이 과정을 <순차적인 조작="">으로 다시 적어봅니다.

13에는 23이 들어 있습니다. 그러니까 23자릿수로 1을 출력하고 13에서 23을 뺀 나머지인 5를 살펴봅니다. 5에 22이 들어 있습니다. 그러니까 22자릿수로 1을 출력하고 5에서 22을 뺀 나머지인 1을 살펴봅니다. 1에는 21이 들어 있지 않습니다. 그러니까 21자릿수로 0을 출력합니다. 다음으로 1에 20이 들어 있는지 살펴봅니다. 들어 있으므로 20자릿수로 1을 출력합니다. 1에서 20을 빼면 0이 남습니다. 이로서 이진수로의 변환이 끝납니다. 이진수 1101이 올바르게 출력됐습니다.

나머지 9, 8, 35를 이진수로 변환하는 과정도 같은 절차를 따릅니다. 위 표를 보고 변환 과정을 따라가보세요.

위 과정을 코드로 옮기면 프로그램이 완성됩니다.

n에는 이진수로 변환할 십진수를 넣습니다.

power에는 n보다 작거나 같은 2의 거듭제곱수들 중 가장 큰 수를 넣습니다. 위 표에서 보듯이 n이 13일 때는 power가 23, n이 9일 때와 8일 때도 power가 23, n이 35일 때는 power가 25입니다.

이렇게 n과 power를 초기화하고 나서, 위 설명의 <순차적인 조작="">을 반복적으로 실행합니다.

반복할 순차적 조작 {

만약, power가 n에 들어 있지 않으면, 0을 출력한다.

그렇지 않고 power가 n에 들어 있으면, 1을 출력하고 n에서 power를 뺀다.

power를 2로 나누어준다. // power가 23이었다면 22으로, 22이었다면 21으로 만들어준다.

}

위 반복문을 언제까지 실행해야 하나? 위 표를 유심히 살펴보면 (어떤 변수 값이 어떤 값보다 큰 동안, 혹은 작은 동안) 실행할지 알 수 있다.

       

P10 (switch 문장: ATM 기계)

현금입출금기계를 작동하는 프로그램을 작성하시오. 프로그램은 사용자에게 메뉴를 보여주고 사용자 입력에 따라 작동합니다. 사용자 계좌에는 초기에 5000원이 들어 있다고 가정합니다. 클래스 이름은 ATMMachine으로 지으시오.

실행화면은 아래와 같습니다. 아래 화면 각각은 ATMMachine 프로그램을 새로 실행시켜 얻은 것입니다.

img

img

img

img

img

img

       

P11 (switch 문장, while 문장: ATM 기계)

위 P8번 프로그램이 아래 예처럼 연속적으로 작동하게 수정하시오. P8번 프로그램의 경우에는 한 번 거래를 하고 나면 프로그램이 끝났습니다. 이 문제에서는 사용자가 종료를 선택할 때까지 계속해서 여러 가지 거래를 할 수 있도록 합니다. 클래스 이름은 ATMMachine2로 지으시오.

실행화면은 아래와 같습니다.

img

힌트: 사용자가 종료(4번)을 선택할 때까지 사용자 입력을 반복적으로 받아 일을 하도록 합니다.

끝.