[JAVA] 2017-2019 프로그래밍 문제 모음

https://ss-o.tistory.com/149

* 위 게시글을 바탕으로 코드 정리를 하였습니다. 


Java

1. 다음 Java 언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오. (2017년 1회)

public class Test001 {
    public static void main(String[] args) {
        int[] a = {3, 4, 10, 2, 5};  // 배열 초기화
        int temp;

        // 배열 정렬
        for (int i = 0; i <= 3; i++) {  // 첫 번째 루프: 0부터 3까지
            for (int j = i + 1; j <= 4; j++) {  // 두 번째 루프: i+1부터 4까지
                if (a[i] < a[j]) {  // 현재 요소가 다음 요소보다 작으면
                    temp = a[i];  // 위치를 바꿈
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }

        // 정렬된 배열 출력
        for (int i = 0; i < 5; i++) {
            System.out.println(a[i]);
        }
    }
}

동작 설명

  1. int[] a = {3, 4, 10, 2, 5}; 배열 초기화
  2. for 루프를 통해 배열을 순회하면서 내림차순 정렬
  3. if 조건을 통해 현재 요소가 다음 요소보다 작으면 위치를 바꿈
  4. 정렬된 배열을 출력

출력 결과

더보기

10
5
4
3
2

 

2. 다음 Java 언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오. (2017년 2회)

public class Test002 {
    public static void main(String[] args) {
        int a = 0, sum = 0;
        while (a < 10) {
            a++;
            if (a % 2 == 1) // 홀수인 경우
                continue;
            sum += a; // 짝수인 경우 sum에 더함
        }
        System.out.println(sum); // 2 + 4 + 6 + 8 + 10 = 30
    }
}

동작 설명

  1. a = 0: 증가 후 1 (홀수, continue)
  2. a = 1: 증가 후 2 (짝수, sum = 2)
  3. a = 2: 증가 후 3 (홀수, continue)
  4. a = 3: 증가 후 4 (짝수, sum = 6)
  5. a = 4: 증가 후 5 (홀수, continue)
  6. a = 5: 증가 후 6 (짝수, sum = 12)
  7. a = 6: 증가 후 7 (홀수, continue)
  8. a = 7: 증가 후 8 (짝수, sum = 20)
  9. a = 8: 증가 후 9 (홀수, continue)
  10. a = 9: 증가 후 10 (짝수, sum = 30)

=> sum은 짝수 2, 4, 6, 8, 10을 더한 값인 30


출력 결과

 

3. 다음은 배열에 저장된 5개의 자료 중 가장 큰 값과 가장 작은 값을 찾아 출력하는 프로그램 Java 언어로 구현한 것이다. 프로그램을 분석하여 괄호에 해당하는 답안을 <답란>에 쓰시오. (2017년 3회)

public class Test003 {
    public static void main(String[] args){
        int a[] = {10, 30, 50, 70, 90};
        int i, max, min;
        max = a[0];
        min = a[0];
        for(i = 0; i < 5; i++){
            if((   ) > max)      // 최대값을 찾기 위한 조건
                max = a[i];
            if((   ) < min)      // 최소값을 찾기 위한 조건
                min = a[i];
        }
        System.out.printf("%d\n", max);  // 최대값 출력
        System.out.printf("%d\n", min);  // 최소값 출력
    }
}

답안

더보기

a[i]

 

4. 다음 Java 언어의 <처리조건>과 <코드>를 보고 괄호(1)~(2)에 적용될 수 있는 가장 적합한 답을 쓰시오. (2018년 1회)

<처리조건>
배열에는 95, 75, 85, 100, 50이 차례대로 저장된다.
배열에 저장된 값을 오름차순으로 정렬하여 출력한다.
public class Test004 {
    public static void main(String[] args){
        int E[] = {(      1      )};
        int i = 0;
        int temp = 0;

        do {
            int j = i + 1;  // j를 i+1로 초기화
            do{
                if(E[i] > (   2   )){  // 오름차순 정렬 조건 수정
                    temp = E[i];
                    E[i] = E[j];
                    E[j] = temp;
                }
                j++;
            } while (j < 5);
            i++;
        } while (i < 4);  

        for (int a = 0; a < 5; a++){
            System.out.printf(E[a] + "\t");
        }
        System.out.println();
    }
}

동작 설명

1. 초기화: 배열 E에 95, 75, 85, 100, 50가 차례대로 저장된다.

2. 정렬 알고리즘:

  • do-while 루프를 사용하여 배열의 각 요소를 순회한다.
  • i는 0부터 시작하여 4까지 증가한다.
  • 내부 do-while 루프에서 j 는 i+1로 초기화되고, 배열의 마지막 요소까지 증가한다.
  • 배열의 두 요소 E[i]와 E[j]를 비교하여 E[i]가 E[j]보다 크면 두 요소를 교환한다.

3. 배열 출력


답안

더보기

1: 95, 75, 85, 100, 50

2: E[j]

 

5. 다음 Java 언어의 <출력>과 <코드>를 보고 괄호 (1), (2)에 가장 적합한 답을 쓰시오. (2018년 2회)

<출력>
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
public class Test005 {
    public static void main(String[] args){
        int[][] a = new int[ (1) ][ (2) ];
        for(int i = 0; i<3; i++){
            for(int j = 0; j<5; j++){
                a[i][j] = i+j;
                System.out.printf("%d", a[i][j]);
            }
            System.out.println();
        }
    }
}

동작 설명

1. 배열 선언: 이차원 배열 a를 선언하고 초기화한다.

2. 이중 루프를 통한 값 할당:

  • 첫 번째 for 루프는 행 인덱스르 0에서 2까지 반복한다.
  • 두 번째 for 루프는 열 인덱스를 0에서 4까지 반복한다.
  • 각 배열 요소 a[i][j]에 i+j 값을 할당한다. 

3. 각 배열 요소를 출력

 

6. 다음은 피보나치 수열의 합계를 구하는 프로그램을 Java 언어로 구현한 것이다. 프로그램을 분석하여 그 실행 결과를 쓰시오. (2018년 3회)

public class Test006 {
    public static void main(String[] args) {
        int a, b, c, sum;
        a = b = 1;  // 첫 두 항을 1로 초기화
        sum = a + b;  // sum은 처음 두 항의 합으로 초기화 (2)

        for(int i = 3; i <= 5; i++){  // 세 번째 항부터 다섯 번째 항까지 계산
            c = a + b;  // 현재 항은 이전 두 항의 합
            sum += c;  // 현재 항을 sum에 추가
            a = b;  // a는 이전 b의 값으로 업데이트
            b = c;  // b는 현재 항의 값으로 업데이트
        }
        System.out.println(sum);  // 최종 합을 출력
    }
}

동작 설명

  • 초기 상태:
    • a = 1, b = 1, sum = 2 (1 + 1)
  • 세 번째 항 (i = 3):
    • c = a + b = 1 + 1 = 2
    • sum = sum + c = 2 + 2 = 4
    • a = 1, b = 2
  • 네 번째 항 (i = 4):
    • c = a + b = 1 + 2 = 3
    • sum = sum + c = 4 + 3 = 7
    • a = 2, b = 3
  • 다섯 번째 항 (i = 5):
    • c = a + b = 2 + 3 = 5
    • sum = sum + c = 7 + 5 = 12
    • a = 3, b = 5

답안

 

7. 다음 Java 언어로 구현한 프로그램을 분석하여 그 실행 결과를 쓰시오. (2019년 1회, 2020년 3회 유사문제 출제)

① class SuperObject{
    public void paint() {
        draw();
    }

    ❺ public void draw() {
        ❻ draw();
        ❾ System.out.println("Super Object");
    } ❿
}

② class SubObject extends SuperObject {
    ❸ public void paint() {
        ❹ super.draw();
    } ⓫

    ❼ public void draw(){
        ❽ System.out.println("Sub Object");
    }
}

public class Test007 {
    public static void main(String[] args) {
        ❶ SuperObject a = new SubObject();
        ❷ a.paint();
    }
}

동작 설명

* 답안 작성 시 주의 사항

- 최근 출제 프로그램 코드 문제는 이 문제처럼 코드에 대한 설명이 없다. 

- 그러므로 C나 Java 코드 문제를 풀 때는 실행 순서대로 디버깅을 수행하면서 문제 해결의 실마리를 찾는 습관을 가지자.

① 클래스 SuperObject 정의

② 클래스 SubObject 정의 후 부모 클래스로 SuperObject를 지정하면서 SuperObject에 속한 변수와 메소드를 상속받는다.

- class A extends B: A 클래스를 선언하면서 B 클래스에서 상속받음으로써 B 클래스의 변수 및 메소드를 사용할 수 있다. 

- 메소드 재정의(오버라이딩): SubObject 클래스에 있는 paint(), draw() 메소드는 SuperObject 클래스에 있는 paint(), draw() 메소드와 이름은 같지만 메소드 안의 실행 코드는 다륻. 이와 같이 부모 클래스에서 정의한 메소드를 자식 클래스에서 다르게 정의해서 사용할 수 있는데, 이를 메소드 오버라이딩이라고 한다. 

❶ [부모클래스명][객체변수명] = new [자식클래스생성자()]: 자식 클래스 생성자로 인스턴스를 생성할 때 자료형을 부모 클래스로 지정하면 생성된 인스턴스는 부모 클래스로 묵시적 클래스 형 변환이 된다. 이렇게 형 변환이 발생했을 때, 부모 클래스와 자식 클래스에 같은 이름의 메소드가 존재하면 호출되는 메소드는 생성되는 인스턴스에 따라 결정된다. 즉 선언한 클래스 자료형이 아닌 생성된 자식 클래스 인스턴스의 메소들르 호출하는데, 이렇게 생성된 인스턴스의 메소드가 호출되는 기술을 가상 메소드라고 한다.

클래스에 속하는 멤버 변수는 인스턴스가 생성될 때마다 새로 생성되지만 메소드는 실행해야 할 코드의 집합이기 때문에 클래스의 인스턴스가 여러 개 생성된다고 해서 메소드가 여러 개 생성되지는 않는다.

일반적으로 프로그램에서 메소들르 호출한다는 것은 그 메소드의 명령 집합이 있는 메모리 위치를 참조하여 명령을 실행하는 것인데, 가상 메소드의 경우에는 가상 메소드의 이름과 실제 메모리 주소가 짝을 이루는 '가상 메소드 테이블'이 만들어진다. 어떤 메소드가 호출되면 이 테이블에서 주소 값을 찾아 해당 메소드의 명령을 수행하는 것이다.

❷ a.paint()는 a 객체의 자료형이 SuperObject이므로 SuperObject.paint()라고 생각할 수 있지만 ❶에서 클래스 형 변환을 수행했고, paint() 메소드가 자식 클래스에서 재정의를 통해 오버라이딩 된 메소드이므로 자식 클래스의 paint() 메소드가 수행된다. SubObject.paint()를 호출한다.

❸ 리턴값과 매개변수가 없는 메소드 paint()의 시작점이다.

❹ 부모 클래스를 호출하는 예약어 super를 사용하였으므로 부모 클래스 draw()메소드를 수행 후 ❺으로 이동한다.

❺ 리턴 값과 매개변수가 없는 메소드 draw()의 시작점이다.

❻ draw()를 수행한다. ❶에서 클래스 형 변환을 수행하였고, draw() 메소드가 자식 클래스에서 재정의를 통해 오버라이딩 된 메소드이므로 자식 클래스의 draw() 메소드를 수행 후 ❼으로 이동한다.

❼ 리턴값과 매개변수가 없는 메소드 draw()의 시작점이다.

❽ 화면에 문자열 "Sub Object"를 출력하고, 다음 줄의 처음으로 커서를 이동시킨다. SubObject 클래스의 draw()메소드가 종료되었으므로 메소드를 호출했던 ❻번의 다음 줄인 ❾번으로 이동한다.

출력 결과: Sub Object

❾ 화면에 문자열 "Super Object"를 출력하고, 다음 줄의 처음으로 커서를 이동시킨다.


출력 결과:

더보기

Sub Object
Super Object

 

8. 다음 Java 언어로 구현한 프로그램을 분석하여 그 실행 결과를 쓰시오. (2019년 1회)

public class Test008 {
    public static void main(String[] args){
        int i, sum = 0;
        for(i = 1; i <= 110; i++){
            if(i%4 == 0)
                sum = sum + 1;
        }
        System.out.printf("%d", sum);
    }
}

동작 방식

1. 반복문에서 i 는 1부터 110까지 증가하며 반복한다. sum은 4로 나누어 떨어지는 수의 개수를 저장할 변수이다.

2. 반복문 실행

  • for 문은 i를 1부터 110까지 반복한다.
  • if 조건문으로 i 가 4로 나눠 떨어지면 sum 을 1 증가시킨다. 

3. 출력 결과: 1부터 110까지 숫자 중에 4의 배수인 수의 개수가 출력된다. 


출력 결과

 

9. 다음 Java 언어로 구현한 프로그램을 분석하여 그 실행 결과를 쓰시오. (2019년 2회)

public class Test009 {
    public static void main(String[] args){
        int numAry[] = new int[5];
        int result = 0;

        for(int i = 0; i < 5; i++)
            numAry[i] = i + 1;

        for(int i:numAry)
            result += i;

        System.out.printf("%d", result);
    }
}

동작 방식

  1. 배열 선언 및 초기화:
    • int numAry[] = new int[5];에서 numAry라는 이름의 정수형 배열을 선언하고, 크기가 5인 배열을 생성한다. 즉, numAry는 [0, 0, 0, 0, 0]으로 초기화
    • int result = 0;에서 result 변수를 선언하고 0으로 초기화
  2. 배열에 값 할당:
    1. for(int i = 0; i < 5; i++) numAry[i] = i + 1;을 통해 반복문을 사용하여 numAry 배열의 각 요소에 값을 할당
      1. numAry[0]에는 1이 할당
      2. numAry[1]에는 2가 할당
      3. numAry[2]에는 3이 할당
      4. numAry[3]에는 4가 할당
      5. numAry[4]에는 5가 할당
    2. 따라서 numAry 배열은 [1, 2, 3, 4, 5]가 된다.
  3. 배열 요소의 합 계산:
    1. 향상된 for문(for(int i:numAry))을 사용하여 numAry 배열의 각 요소를 순회하면서 result += i;를 수행한다.
    2. result 변수에는 numAry 배열의 모든 요소의 합계가 누적된다.
  4. 결과 출력:

출력 결과

 

10. 다음 Java 언어로 구현한 프로그램을 분석하여 그 실행 결과를 쓰시오. (2019년 2회)

public class Test010 {
    public static int[] arr(int[] a){
        int i, j, sw, temp, n = 5;
        if(a[0] == 0 || a[0] < 1)
            return a;

        for(i = 0; i < n-1; i++){
            sw = i;
            for(j = i+1; j < n; j++) {
                if(a[j] > a[sw])
                    sw = j;
            }
            temp = a[i];
            a[i] = a[sw];
            a[sw] = temp;
        }
        return a;
    }

    public static void main(String[] args){
        int i;
        int n[] = {4, 3, 5, 2, 10};
        arr(n);
        for(i = 0; i < 5; i++)
            System.out.println(n[i]);
    }
}

동작 방식

  1. if문
    • if(a[0] == 0 || a[0] < 1) 조건문은 배열의 첫 번째 요소가 0이거나 1보다 작을 경우, 원래 배열 a를 그대로 반환한다.
    • 그렇지 않은 경우, 배열을 내림차순으로 정렬하는 선택 정렬 알고리즘을 수행한다.
  2. 선택 정렬 알고리즘:
    • for(i = 0; i < n-1; i++)에서 외부 반복문은 배열의 처음부터 끝에서 두 번째 요소까지 반복한다.
    • sw 변수는 현재 인덱스 i를 가리키며, 내부 반복문(for(j = i+1; j < n; j++))에서는 sw 이후의 요소들을 검사하여 가장 큰 값을 찾는다.
    • if(a[j] > a[sw]) 조건문을 통해 sw의 값보다 큰 요소가 발견되면 sw를 해당 인덱스 j로 업데이트한다.
    • 내부 반복문이 끝나면, sw에 저장된 가장 큰 값의 인덱스를 사용하여 현재 인덱스 i와 sw에 있는 값을 교환한다.
  3. 결과 출력

출력 결과

더보기

10
5
4
3
2