1. 문제

/******************************************************************************
 * 문제 3-2
 ******************************************************************************/
// 새로운 프로젝트와 Main.java 소스파일을 만든 후 [문제 3-1]에서 작성한 소스코드를 복사해서 삽입하라.
// [문제 3-2] 실행 결과를 참고하여 아래 코드를 완성하라.

 

public class Main
{
    public static int[][] makeArray(Scanner s) {
        기존 함수를 다음과 같이 수정하라.
        출력 결과를 참고하여 비정방형 배열 arr[][]을 생성한 후 
        해당 배열의 각 원소를 출력 결과처럼 초기화한 후 배열을 리턴한다.
    }

    public static void printArray(int arr[][]) {
        기존 코드와 동일
    }
    
    public static void main(String[] args) {
        기존 코드와 동일함
    }
}

 

해당 문제는 1번 문제에서 만들었던 정방형 배열을 비정방형으로 바꾸는 꽤나 쉬운 문제였다.

 

2. 전체코드

import java.util.*;

class Main {
   public static int[][] makeArray(Scanner s) {
      System.out.print("array size? ");
      int length = s.nextInt();
      int arr[][] = new int[length][];
      for(int i=0; i<length; i++){
        arr[i] = new int[length - i]; //비정방형 배열 생성
        int colLength = arr[i].length;
        int value = i; //행마다 시작값이 바뀌게 설정.
        for(int j=0; j<colLength; j++){
          arr[i][j] = value++;
        }
      }
      return arr;
    }

    public static void printArray(int arr[][]) {
        //출력 결과를 참고하여 2차원 배열 arr[][]의 모든 원소들을 출력한다.
      for(int i=0; i<arr.length; i++){
        System.out.print("arr["+i+"] ");
        for(int j =0; j < arr[i].length; j++){
          System.out.print(arr[i][j]+" ");
        }
        System.out.println();
      }
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int arr[][];
        
        while(true){ // 아래 과정을 계속 반복 수행한다.
            arr = makeArray(scanner);
            printArray(arr);
            System.out.print("continue? ");
            String str = scanner.next();
            System.out.println();
            //입력된 단어가 "yes"이면 계속 반복 수행하고 "yes"가 아니면 여기서 반복을 중단한다.
            if(!str.equals("yes")) break;
        }
 
        scanner.close();
        System.out.println("Done.");
    }
}

 

3. 대충 이해하기

3-1번 문제와 비교하여 makeArray 메소드만 바뀌었고, 해당 부분도 정방형 배열에서 비정방형 배열로 바뀐 점이 핵심이다.

3-1. 각 행의 시작값 구하기

시작값 구하기

 

비정방형 배열에서 각 행의 시작값을 보면 각 행과 똑같은 것을 볼 수 있다.

0행은 0부터 시작

1행은 1부터 시작

2행은 2부터 시작

즉 코드로는 int value = 각 행의 index; 로 나타낼 수 있었다.

 

3-2. 각 행의 길이 구하기

각 행의 길이는 배열의 사이즈부터 시작해서 각 행을 반복할 수록 1씩 줄어드는 것을 볼 수 있었다.

코드로 나타내면 다음과 같다.

 

 for(int i=0; i<length; i++){ //행을 반복하는 FOR문
        arr[i] = new int[length - i]; //비정방형 배열 생성 (i가 커질수록 점점 작아진다.)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'코딩이야기 > 연습문제' 카테고리의 다른 글

[라이브코딩 연습] JAVA 실습문제 4-2  (0) 2022.11.01
[라이브코딩 연습] JAVA 실습문제 4-1  (0) 2022.11.01
JAVA 실습문제 3-1  (0) 2022.10.28
JAVA 실습문제 3-3  (0) 2022.10.25

1. 문제

/****************************************************************************** *

문제 3-1

******************************************************************************/

// 새로운 프로젝트와 Main.java 소스파일을 만든 후 아래 코드를 복사하여 소스파일에 삽입하라.

// [문제 3-1] 실행 결과를 참고하여 아래 코드를 완성하라.

import ...;

public class Main
{
    public static int[][] makeArray(Scanner s) {
        출력 결과를 참고하여 사용자로부터 정방형 배열 크기("array size? ")를 입력받고 배열을 생성한다. 
        필요한 배열의 원소들을 적절히 초기화한 후 배열을 리턴한다. 
        (초기화하지 않은 배열 원소는 0으로 자동 설정된다.)
    }

    public static void printArray(int arr[][]) {
        출력 결과를 참고하여 2차원 배열 arr[][]의 모든 원소들을 출력한다.
    }
    
    public static void main(String[] args) {
        Scanner scanner = 스캐너 객체 생성;
        int arr[][];
        
        { // 아래 과정을 계속 반복 수행한다.
            arr = makeArray(scanner);
            printArray(arr);
            System.out.print("continue? ");
            문자열 단어 하나를 입력 받음
            System.out.println();
            입력된 단어가 "yes"이면 계속 반복 수행하고 "yes"가 아니면 여기서 반복을 중단한다.
        }
 
        스캐너 객체 닫기;
        System.out.println("Done.");
    }
}




===============================================================================
==  [문제 3-1] 실행 결과
=============================================================================== 
array size? 2
arr[0] 0 1 
arr[1] 2 3 
continue? yes

array size? 3
arr[0] 0 0 1 
arr[1] 0 2 3 
arr[2] 4 5 6 
continue? yes

array size? 4
arr[0] 0 0 0 1 
arr[1] 0 0 2 3 
arr[2] 0 4 5 6 
arr[3] 7 8 9 10 
continue? yes

array size? 5
arr[0] 0 0 0 0 1 
arr[1] 0 0 0 2 3 
arr[2] 0 0 4 5 6 
arr[3] 0 7 8 9 10 
arr[4] 11 12 13 14 15 
continue? no

Done.

 

 

2. 전체코드

import java.util.*;

public class Main
{
    public static int[][] makeArray(Scanner s) {
      System.out.print("array size? ");
      int length = s.nextInt();
      int arr[][] = new int[length][length];
      int number = 1;
      for(int i=0; i<length; i++){
        for(int j=length - i - 1; j<length; j++){
          arr[i][j] = number++;
        }
      }
      return arr;
    }

    public static void printArray(int arr[][]) {
        //출력 결과를 참고하여 2차원 배열 arr[][]의 모든 원소들을 출력한다.
      for(int i=0; i<arr.length; i++){
        System.out.print("arr["+i+"] ");
        for(int j =0; j < arr[i].length; j++){
          System.out.print(arr[i][j]+" ");
        }
        System.out.println();
      }
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int arr[][];
        
        while(true){ // 아래 과정을 계속 반복 수행한다.
            arr = makeArray(scanner);
            printArray(arr);
            System.out.print("continue? ");
            String str = scanner.next();
            System.out.println();
            //입력된 단어가 "yes"이면 계속 반복 수행하고 "yes"가 아니면 여기서 반복을 중단한다.
            if(!str.equals("yes")) break;
        }
 
        scanner.close();
        System.out.println("Done.");
    }
}

 

3. 대충 이해하기

내가 생각하는 가장 핵심 부분은 makeArray 메소드의 값을 집어넣는 부분이다.

결과화면 중 일부 캡쳐

결과를 쭉 나열해서 보니 하나의 공식을 발견할 수 있었는데 해당 공식은 아래와 같다.

값을 삽입할 첫 열(컬럼) : 입력한 사이즈에서 현재 입력될 행을 빼고 -1 (배열의 인덱스는 0부터 시작) 이라는 공식을 발견할 수 있었다.

 

이 내용을 그대로 JAVA로 구현한 것이 makeArray메소드의 이중 for문 부분이다.

'코딩이야기 > 연습문제' 카테고리의 다른 글

[라이브코딩 연습] JAVA 실습문제 4-2  (0) 2022.11.01
[라이브코딩 연습] JAVA 실습문제 4-1  (0) 2022.11.01
JAVA 실습문제 3-2  (0) 2022.10.28
JAVA 실습문제 3-3  (0) 2022.10.25

0. 문제[텍스트]

/******************************************************************************
 * 문제 3-3
 ******************************************************************************/
// 새로운 프로젝트와 Main.java 소스파일을 만든 후 [문제 3-2]에서 작성한 소스코드를 복사해서 삽입하라.
// [문제 3-3] 실행 결과를 참고하여 아래 코드를 완성하라.

public class Main
{
    public static int[][] makeArray(Scanner s) { 기존 코드와 동일 }

    public static void printArray(int arr[][]) { 기존 코드와 동일 }
    
    public static void printArrayElement(Scanner s, int arr[][]) {
        int r = 0, c = 0;
        "dividen? " 와 "divisor? " 를 출력하고 분자와 분모를 각각 입력 받는다.
        분자를 분모로 나눈 몫을 행 변수 r에 저장하고 
        분자를 분모로 나눈 나머지를 열 변수 c에 저장
        arr[r][c] 원소를 출력결과처럼 적절히 출력하고 리턴
        위 과정을 처리하는 도중 예외가 발생할 경우 출력결과처럼 에러 원인을 출력하고 리턴
    }

    public static void main(String[] args) {
        Scanner scanner = 스캐너 객체 생성;
        int arr[][];

 

        arr = makeArray(scanner);
        printArray(arr);
        System.out.println();

 


        { // 아래 과정을 계속 반복 수행한다.

            printArrayElement(scanner, arr);

           System.out.print("continue? ");

           문자열 단어 하나를 입력 받음

           System.out.println();

            입력된 단어가 "yes"이면 계속 반복 수행하고 "yes"가 아니면 여기서 반복을 중단한다.

        }

        스캐너 객체 닫기;

        System.out.println("Done.");

    }
}

1. 문제소개 및 실행예시

JAVA 문제 3-3

 

JAVA 문제 3-3 실행예시

 

2. 전체코드

import java.util.Scanner;
import java.util.InputMismatchException;
  
public class Main{
    public static int[][] makeArray(Scanner s) {
      int size = 0;
      int tmp = 0;
      System.out.print("array size? ");
      size = s.nextInt();
      int size_tmp = size;
      int arr[][] = new int[size][];

      for(int i = 0; i<size; i++)
        arr[i] = new int[size_tmp--];
      
      for(int i = 0; i< size; i++){
        for(int j = 0; j< arr[i].length; j++){
          arr[i][j] = tmp+j+i;
        }
      }
      return arr;
    }

    public static void printArray(int arr[][]) {
      int size = arr.length;
      for(int i = 0; i< size; i++){
        System.out.print("arr["+i+"] ");
        for(int j =0; j < arr[i].length; j++){
          System.out.print(arr[i][j]+" ");
        }
        System.out.println();
      }
      
    }
    public static void printArrayElement(Scanner s, int arr[][]) {
      int r = 0, c = 0;
      try{
        System.out.print("dividen? ");
        int divd = s.nextInt();
        System.out.print("divisor? ");
        int divs = s.nextInt();
        r = divd/divs;
        c = divd%divs;
        System.out.println("arr["+r+"]["+c+"]: "+arr[r][c]);
      }
      catch(ArrayIndexOutOfBoundsException e){
        System.out.println("arr["+r+"]["+c+"]: "+" array index is out of BOUNDS");
      }
      catch(InputMismatchException e){
        System.out.println("input an INTEGER");
        s.nextLine();
      }
      catch(ArithmeticException e){
        System.out.println("divisor is ZERO");
      }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int arr[][];
                
        arr = makeArray(scanner);
        printArray(arr);
        System.out.println();

        while(true){ 
            printArrayElement(scanner, arr);
            System.out.print("continue? ");
            String s = scanner.next();
            System.out.println();
            if(s.equals("yes"))
              continue;
            else
              break;
        }
 
        scanner.close();
        System.out.println("Done.");
    }
}

 

3. 대충설명

printArrayElement 메소드를 만들면 되는 문제였다.

해당 문제는 try~catch문 에 대해 알고 있으면 쉽게 풀 수 있었다.

try블록 뿐 아니라 catch에서도 접근하기 위해서 try 블록 밖에 선언

② try 안에 있는 내용을 실행하는 도중 에러가 나면 catch문으로 넘어간다.

③ catch문은 선언한 순서대로 실행된다. 즉, 에러가 ArrayIndexOutOfBoundException인지 검사하고 아니라면 InputMismatchException으로 넘어간다.

 

여기에서 친구들이 어려워 했던 건

> 2 b 를입력했을 때이다.

원하는 실행결과는 아래와 같은데 

원하는 실행결과

자꾸 continue? 에서 아무것도 입력하지 안았는데 Done. 이 떠버린다는 것..

잘못된 실행결과

 

 이유는 바로 scanner에 b가 제대로 빠지지 않아서 그렇다.

  1. 사용자가 2 b를 공백으로 구분하여 입력
  2. Scanner의 Buffer에는 2와 b가 저장
  3. scanner.nextInt() 메소드에 의해 차례대로 변수에 저장
  4. int divs = s.nextInt() 코드에서는 b를 int로 읽을 수 없기 때문에 에러가 발생하여 catch문으로 빠지게 된다.
  5. catch문 중에 InputMismatchException 에러이므로 해당 부분이 실행된 후 해당 메소드는 종료된다. (더 이상 실행할 코드가 없음)
  6. 그런데 printArrayElement 메소드 다음에 실행되는 부분에서 scanner.next()를 하게되면?
  7. 아직 빠지지 않은 "b"가 출력이 되어버린다. 그래서 yes와 다르니까 break; 문을 만나 바로 종료되게 된다.

이 부분을 해결하기 위해서는 InputMismatchException 을 처리하는 catch문 쪽에 sc.nextLine()이라고 현재 scanner에 있는 값들을 빼내 주면 해결된다.

'코딩이야기 > 연습문제' 카테고리의 다른 글

[라이브코딩 연습] JAVA 실습문제 4-2  (0) 2022.11.01
[라이브코딩 연습] JAVA 실습문제 4-1  (0) 2022.11.01
JAVA 실습문제 3-2  (0) 2022.10.28
JAVA 실습문제 3-1  (0) 2022.10.28

+ Recent posts