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

개발을 하다보면 배열에 있는 값을 랜덤으로 섞어서 다른 배열을 만들어야할 때가 있다.

 

 

그때그때 짜기 보다는 그냥 하나 만들어두고 복붙하는게 좋을거같아서 끄적여본다 ㅎㅎ.

    const origin = [1,2,3,4,5,6,7,8,9];
    const shuffle = shuffleFunc(origin);

    function shuffleFunc(origin){
        const shuffle = [];    
        const dummy = origin.slice();
        
        while(dummy.length > 0){
            const index = Math.floor(Math.random() * dummy.length); // 0 <= x < length
            shuffle.push(dummy[index]);
            dummy.splice(index,1); //버려준다.
        }
        return shuffle;
    }

 

[설명]

1. 변수 설명

const shuffle 배열은 무작위하게 섞인 항목들이 들어갈 배열이 된다.
const dummy 배열은 해당 함수가 splice를 사용하여 구현되기 때문에 원본배열을 손상시키지 않기 위해서 
원본배열의 참조값을 가지고 있는 배열일 뿐이다.

 

2. 주요 로직

[ 무작위 값 선택 ] 

주의할 점은 배열의 범위를 넘어서는 index를 선택하면 안된다.

Math.random() 은 무작위로 0 <= x < 1의 값을 반환한다.

우리는 dummy 배열의 인덱스를 무작위로 추출해야하므로 dummy배열의 length를 활용한다.

 

Math.random() * dummy.length 의 반환값은 아래와 같을 것이다.

0 <= x < dummy.length 즉, 위의 예시에서는 0 <= x < 9 (0~8까지)

해당 식의 반환값은 현재 dummy 길이를 초과하지 않는 index값이 반환될 것이고, shuffle에 해당 index의 값을 넣어주기만 하면된다.

 

[ 후처리 ]

index하나를 무작위로 선택하여 결과 배열(shuffle)에 넣었으니 선택된 index는 다시 선택되지 않도록 처리해줘야한다.

 

그것을 splice로 처리하고 있다.

 

splice(i, N)  하면 i번째 부터 N개까지 추출하여 배열로 반환하는 메소드이며, 해당 메소드는 대상이 되는 원본배열을 수정해버리기 때문에 주의해야한다. (slice와 다름 주의!!) 

 

결과적으로 splice(index, 1)을 하게되면 해당 index의 항목이 빠지게 되는 효과를 볼 수 있다.

 

[ 정리 ]

const index = Math.floor(Math.random() * dummy.length); ===> 4가 나왔다고 가정

 

 

shuffle.push(dummy[index]);

 


           

dummy.splice(index,1);

 

 

 

 

 

+ Recent posts