컴퓨터는 잘못이 없다..

[JAVA]연습문제 본문

공부/JAVA

[JAVA]연습문제

도토리까꿍v 2024. 5. 5. 17:03
Contents 접기

Practice ①

practice1

practice1 문제

Practice1
===

문제 설명
---
입력된 정수 자료형의 숫자를 거꾸로 변환하는 프로그램을 작성하세요.

- 예를들어 12345가 입력되면 54321로 변환하여 출력하면 된다.
- 100의 경우 001이 되는데 이 경우 1만 출력하도록 한다.


입출력 예시
---
|입력|결과|
|---|---|
|12345|54321|
|-12345|-54321|
|100|1|
|0|0|

practice1 답

public class Practice1 {
    public static void solution(int num) {
        int numReverse = 0;
        boolean isMinus = false;

        // 음수 체크하는 부분
        if (num < 0) {
            isMinus = true;
            num *= -1;
        }

        // 나머지 연산, 나누기 연산을 이용하여 거꾸로 변환하는 부분
        while (num > 0) {
            int r = num % 10;
            num /= 10;
            numReverse = numReverse * 10 + r;
        }

        System.out.println(isMinus ? numReverse * -1 : numReverse);
    }

    public static void main(String[] args) {
        // Test code
        solution(12345);
        solution(-12345);
        solution(100);
        solution(0);
    }
}

└practice1

숫자 거꾸로 돌리기

1. 나머지 연산으로 더해줄 숫자 구하기

2. 원 숫자를 나눠서 더해줄 숫자 빼버리기

3. 더해줄 숫자를 10곱해서 쌓아주기

practice2

practice2 문제

Practice2
===

문제 설명
---
아스키 코드는 미국정보교환표준부호를 의미한다.  

영어로 American Standard Code for Information Interchange 이며, 줄여서 ASCII 라고 한다.  

문자를 사용하는 대부분의 장치에서 사용하며 문자 인코딩 방식에 아스키를 기초로 두고 있다.

다음은 아스키의 특징이다.
- 7비트로 구성
- 총 128개의 문자로 구성 (출력 불가능한 제어문자 33개, 출력 가능한 문자 95개)
- 출력 가능한 문자들은 52개의 영문 알파벳 대소문자와, 10개의 숫자, 32개의 특수 문자, 1개의 공백 문자로 이루어진다.

이번 문제에서는 아스키 코드 중 알파벳에 대해서,  
사용자가 입력한 알파벳의 대소문자를 변경하는 프로그램을 작성하시오. 


입출력 예시
---
|입력|결과|
|---|---|
|a|A|
|b|B|
|C|c|
|D|d|

practice2 답

import java.util.Scanner;

public class Practice2 {
    public static void solution() {
        // 입력 받는 부분
        Scanner sc = new Scanner(System.in);
        System.out.print("알파벳 입력: ");
        char input = sc.nextLine().charAt(0);
        int output = 0;

        // 대소문자 간격
        int step = (int)'a' - (int)'A';
//        a = 97
//        z = 122
//        A = 65
//        Z = 90
        //a를 A로 변환시키려면 대소문자 간격을 구해서 빼주면 되고
        //A를 a로 변환시키려면 대소문자 간격을 구해서 더해주면 된다.

        // 입력 값 예외처리
        if (input >= 'a' && input <= 'z') { //소문자 -> 대문자
            output = (int)input - step;
            System.out.println("대문자 변환: " + (char)output);
        } else if (input >= 'A' && input <= 'Z'){ //대문자 -> 소문자
            output = (int)input + step;
            System.out.println("소문자 변환: " + (char)output);
        } else {
            System.out.println("입력하신 값은 알파벳이 아닙니다.");
        }
    }

    public static void reference() {
        int a = (int)'a';
        System.out.println("a = " + a);
        int z = (int)'z';
        System.out.println("z = " + z);
        int A = (int)'A';
        System.out.println("A = " + A);
        int Z = (int)'Z';
        System.out.println("Z = " + Z);
        int etc = (int)'%';
        System.out.println("etc = " + etc);
    }

    public static void main(String[] args) {
        reference();    // 아스키 코드 참고
        solution();
    }
}

└ practice2 

a를 A로 변환시키려면 대소문자 간격을 구해서 빼주면 되고
A를 a로 변환시키려면 대소문자 간격을 구해서 더해주면 된다.

마찬가지로 다른 알파벳들도 차이만큼 더해주고 빼주면 구할 수 있다.

practice3

practice3 문제

Practice3
===

문제 설명
---
자바의 String 자료형에는 많은 연산자 기능들이 있다.

프로그래밍의 기본기를 익히기 위해 일부 연산자들을 제한하고 다음의 기능을 구현하려 한다.
- String 의 replace 기능 구현
- String의 replace, indexOf, contains를 사용하지 않고 구현한다.


입출력 예시
---
|입력 문자열|from|to|출력|
|---|---|---|---|
|"Hello Java, Nice to meet you! Java is fun!"|"Java"|"자바"|"Hello 자바, Nice to meet you! 자바 is fun!"|
|POP|P|W|WOW|

practice3 답

public class Practice3 {
    public static String solution(char[] str, char[] find, char[] to) {
        int idx = 0;
        // 최종 변경된 데이터 담을 변수
        String replaceStr = "";
        // 중간 중간 업데이트에 사용할 변수
        char[] replaceBucket = str.clone();

        // 문자열 내의 모든 find 에 해당하는 부분을 찾아서 to로 변경할 것
        // do while 로 우선 한 번 찾아보고 반복하여 진행
        do {
            // find 부분의 index 찾을 함수 별도로 작성
            idx = findIndex(replaceBucket, find);

            
            if (idx != -1) {
                // 우선 find 에 해당하는 idx 전까지는 기존 데이터로 업데이트
                for (int i = 0; i < idx; i++) {
                    replaceStr += replaceBucket[i];
                }
                
                // 그 다음 변경할 to로 업데이트
                for (int i = 0; i < to.length; i++) {
                    replaceStr += to[i];
                }
                
                // 그리고 find 이 후의 잔여 데이터 업데이트
                for (int i = idx + find.length; i < replaceBucket.length; i++) {
                    replaceStr += replaceBucket[i];
                }

                // replaceBucket 을 방금 변경된 replacStr 로 업데이트
                replaceBucket = replaceStr.toCharArray();
                // 그 다음 변경을 위해 다시 ""로 초기화
                replaceStr = "";
            }
        } while(idx != -1);

        replaceStr = new String(replaceBucket);
        return replaceStr;
    }

    public static int findIndex(char[] str, char[] find) {
        int idx = -1;
        boolean isMatch = false;

        for (int i = 0; i < str.length; i++) {
            // find 의 첫 글자와 같은지 확인 + 그 때의 str 에 남은 길이가 find 보다 크거나 같은지 확인 후 각 자리 비교
            if (str[i] == find[0] && str.length - i >= find.length) {
                isMatch = true;
                for (int j = 1; j < find.length; j++) {
                    // 하나라도 같지 않은 경우 false 로 변경 후 break
                    if (str[i + j] != find[j]) {
                        isMatch = false;
                        break;
                    }
                }
            }

            // find 부분 찾았으면 idx 업데이트 후 break
            if (isMatch) {
                idx = i;
                break;
            }
        }

        return idx;
    }

    public static void main(String[] args) {
        // Test code
        String str = "Hello Java, Nice to meet you! Java is fun!";
        String find = "Java";
        String to = "자바";

        // 기존 String replace
        System.out.println(str.replace(find, to));

        // 자체 구현 replace
        char[] strExArr = str.toCharArray();
        char[] findArr = find.toCharArray();
        char[] toArr = to.toCharArray();
        System.out.println(solution(strExArr, findArr, toArr));

        strExArr = "POP".toCharArray();
        findArr = "P".toCharArray();
        toArr = "W".toCharArray();
        System.out.println(solution(strExArr, findArr, toArr));
    }
}

└ practice3

String 의 replace연산자를 쓰지 않고 직접 구현함

practice4

practice4 문제

Practice4
===

문제 설명
---

여러가지 별찍기 연습을 해보자.  
반복문과 조건문의 연습에는 과연 별찍기 만한 것이 없다.

아래 5가지 별 찍기 타입이 있다.
- 아래 모양은 N (별 출력 행의 수)이 3일 떄의 출력 결과 들이다.

|타입|모양|
|---|---|
|1|*** <br> *** <br> ***|
|2|* <br> ** <br> ***|
|3|&nbsp;&nbsp;* <br> &nbsp;** <br> ***|
|4|&nbsp;&nbsp;* <br> &nbsp;*** <br> *****|
|5|&nbsp;&nbsp;* <br> &nbsp;*** <br> &nbsp;&nbsp;*|


별 출력 행의 수 N과 별 타입 T가 주어질 때 해당 별 모양을 출력하는 프로그램을 작성하세요.  
(N은 홀수)


입출력 예시
---
|N|T|출력|
|---|---|---|
|3|1|*** <br> *** <br> ***|
|3|2|* <br> ** <br> ***|
|3|3|&nbsp;&nbsp;* <br> &nbsp;** <br> ***|
|3|4|&nbsp;&nbsp;* <br> &nbsp;*** <br> *****|
|7|5|&nbsp;&nbsp;&nbsp;* <br> &nbsp;&nbsp;*** <br> &nbsp;***** <br> ******* <br> &nbsp;***** <br> &nbsp;&nbsp;*** <br> &nbsp;&nbsp;&nbsp;*|

practice4 답

public class Practice4 {
    public static void solution(int n, int type) {
        // 각 타입별 구분하여 함수 호출
        if (type == 1) {
            type1(n);
        } else if (type == 2) {
            type2(n);
        } else if (type == 3) {
            type3(n);
        } else if (type == 4) {
            type4(n);
        } else if (type == 5) {
            type5(n);
        }
    }

    public static void type1(int n) {
        System.out.println("== Type1 ==");
        // n x n 으로 출력
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void type2(int n) {
        System.out.println("== Type2 ==");
        // i에 따라 j를 늘려가며 출력
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i + 1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void type3(int n) {
        System.out.println("== Type3 ==");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (j < n - i - 1) {    // 공백 부분 줄여가며 출력
                    System.out.print(" ");
                } else {
                    System.out.print("*");
                }
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void type4(int n) {
        System.out.println("== Type4 ==");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n - i - 1; j++) {   // 공백 부분 줄여가며 출력
                System.out.print(" ");
            }
            
            for (int j = 0; j < i * 2 + 1; j++) {   // i에 따라 j는 i * 2 + 1 로 늘려주며 출력
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void type5(int n) {
        System.out.println("== Type5 ==");

        // 상단
        for (int i = 0; i <= n / 2; i++) {
            for (int j = 0; j < n / 2 - i; j++) {
                System.out.print(" ");
            }

            for (int j = 0; j < i * 2 + 1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        // 하단
        for (int i = n / 2; i > 0; i--) {
            for (int j = 0; j < n / 2 + 1 - i; j++) {
                System.out.print(" ");
            }

            for (int j = 0; j < i * 2 -1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }

        System.out.println();
    }

    public static void main(String[] args) {
        // Test code
        solution(3, 1);
        solution(3, 2);
        solution(3, 3);
        solution(3, 4);
        solution(7, 5);
    }
}

practice5

practice5 문제

Practice5
===

문제 설명
---
n개의 데이터가 height 배열에 주어졌다.  
height 배열의 각각의 원소는 아래 그림과 같이 각 벽에 대한 높이를 의미한다.

이와 같이 높이 값들이 주어졌을 때,  
이 중에서 어떤 두 벽을 고르면 가장 많은 물을 담을 수 있는지를 확인하고  
그 때의 면적을 출력하세요.

![img_1.png](../imgs/img_1.png)

입출력 예시
---
|입력|출력|
|---|---|
|1, 8, 6, 2, 5, 4, 8, 3, 7|49|
|5, 3, 9, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2|26|

practice5 답

public class Practice5 {
    public static int solution(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int maxArea = 0;

        while (left < right) {
            // # 1
            int x = (right - left);
            int y = height[left] < height[right] ? height[left] : height[right];
            int curArea = x * y;
            maxArea = maxArea > curArea ? maxArea : curArea;

            // # 2
//            curArea = (right - left) * Math.min(height[left], height[right]);
//            maxArea = Math.max(maxArea, curArea);

            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }

        return maxArea;
    }

    public static void main(String[] args) {
        // Test code
        int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        System.out.println(solution(height));

        height = new int[]{5, 3, 9, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
        System.out.println(solution(height));

    }
}

└practice5

int x = (right - left);

int y = height[left] < height[right] ? height[left] : height[right];
int curArea = x * y;

 

위 3줄을 아래 한줄로 줄일 수 있음
curArea = (right - left) * Math.min(height[left], height[right]);

practice②

practice1

practice1 문제

Practice1
===

문제 설명
---
로마 숫자 표기를 정수형으로 변환하는 프로그램을 작성하세요.

로마 숫자 표기법은 I, V, X, L, C, D, M 으로 이루어져있다.

|로마 숫자|정수형|
|---|---|
|I|1|
|V|5|
|X|10|
|L|50|
|C|100|
|D|500|
|M|1000|


로마 숫자 표기 방식
* 큰 기호에서 작은 기호 방향으로 작성 (XI, VI, II, ...)
* 다음의 경우 작은 기호가 큰 기호 앞에 올 수 있다.
  * I 는 V 와 X 의 앞에 올 수 있다. (IV: 4, IX: 9)
  * X 는 L 과 C 의 앞에 올 수 있다. (XL: 40, XC: 90)
  * C 는 D 와 M 의 앞에 올 수 있다. (CD: 400, CM: 900)
  
    
입출력 예시
---

|입력|출력|
|---|---|
|"III"|3|
|"IV"|4|
|"VI"|6|
|"XIII"|13|
|"XXVI"|26|
|"MCMXCIV"|1994|

practice1 답

import java.util.HashMap;

public class Practice1 {
    public static void solution(String s) {
        // 해시 맵으로 로마 숫자 표기 우선 초기화
        HashMap<Character, Integer> map = new HashMap<>();
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);
        
        int sum = 0;
        char[] arr = s.toCharArray();
        for (int i = 0; i < arr.length - 1; i++) {
            // 작은 표기가 앞에 온 경우 뺌
            if (map.get(arr[i]) < map.get(arr[i + 1])) {
                sum -= map.get(arr[i]);
            } else { // 일반 표기 순서의 경우 더함
                sum += map.get(arr[i]);
            }
        }
        sum += map.get(arr[arr.length - 1]);
        System.out.println(sum);
    }

    public static void main(String[] args) {
        // Test code
        solution("III");
        solution("IV");
        solution("VI");
        solution("XIII");
        solution("XXVI");
        solution("MCMXCIV");
    }
}

practice2

practice2 문제

Practice2
===

문제 설명
---
정수형 숫자를 로마 숫자 표기로 변환하는 프로그램을 작성하세요.

로마 숫자 표기법은 I, V, X, L, C, D, M 으로 이루어져있다.

|로마 숫자|정수형|
|---|---|
|I|1|
|V|5|
|X|10|
|L|50|
|C|100|
|D|500|
|M|1000|


로마 숫자 표기 방식
* 큰 기호에서 작은 기호 방향으로 작성 (XI, VI, II, ...)
* 다음의 경우 작은 기호가 큰 기호 앞에 올 수 있다.
    * I 는 V 와 X 의 앞에 올 수 있다. (IV: 4, IX: 9)
    * X 는 L 과 C 의 앞에 올 수 있다. (XL: 40, XC: 90)
    * C 는 D 와 M 의 앞에 올 수 있다. (CD: 400, CM: 900)

입출력 예시
---

|입력|출력|
|---|---|
|3|"III"|
|4|"IV"|
|6|"VI"|
|13|"XIII"|
|26|"XXVI"|
|1994|"MCMXCIV"|

practice2 답

public class Practice2 {

    public static String solution(int num){
        String result = "";
        // 로마 숫자 표기 방법 규칙 적용 역순 나열
        String[] roman = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };

        int i = 0;
        // 입력 num 이 0보다 큰 동안
        while (num > 0) {
            // 로마 숫자 표기 법 중 큰 수부터 현재 num 에서 뺄 수 있는지 체크
            while (num >= values[i]) {
                num -= values[i];
                result += roman[i];
            }
            i++;
        }

        return result;
    }

    public static void main(String[] args) {
        // Test code
        System.out.println(solution(3));
        System.out.println(solution(4));
        System.out.println(solution(6));
        System.out.println(solution(13));
        System.out.println(solution(26));
        System.out.println(solution(1994));
    }
}

practice3

practice3 문제

Practice3
===

문제 설명
---
간단한 편집기를 구현하려고 한다.

편집기에는 문자열과 편집 명령어가 주어지는데, 명령어의 동작은 다음과 같다.
- L : 커서를 왼쪽으로 한 칸 옮김 (커서가 문장의 맨 앞이면 무시)
- D	: 커서를 오른쪽으로 한 칸 옮김 (커서가 문장의 맨 뒤이면 무시)
- B	: 커서 왼쪽에 있는 문자를 삭제 (커서가 문장의 맨 앞이면 무시)
- P x : x라는 문자를 커서 왼쪽에 추가

여기서 커서는 문자열에서 편집이 시작되는 기준 위치로,  
문장의 맨 앞, 맨 뒤, 중간에 위치할 수 있다.

편집기에 문자열과 명령어들이 주어졌을 때,  
편집을 완료한 후의 문자열을 출력하는 프로그램을 작성하시오.  
(초기 커서의 위치는 문장의 맨 뒤에서 시작한다.)  
(문자열은 소문자만 입력 가능하다.)


입출력 예시
---
|초기 문자열|명령어|결과 출력|
|---|---|---|
|"aba"|"L B"|"aa"|
|"abcd"|"P x L P y"|"abcdyx"|
|"abc"|"L L L P x L B P y"|"yxabc"|
|"a"|"B B L L D D P a P b P c"|"abc"|

practice3 답

import java.util.ArrayList;

public class Practice3 {
    public static String solution(String input, String cmd) {
        // 문자열의 편집이 빈번할 때 유리한 StringBuffer 로 변환하여 사용
        StringBuffer sb = new StringBuffer(input);
        ArrayList<String> cmdArr = new ArrayList<>();

        // 명령어들 분할하여 배열에 추가
        for (String s: cmd.split(" ")) {
            cmdArr.add(s);
        }

        // 초기 커서 위치
        int curSor = sb.length();
        // 명령어 배열의 인덱스로 사용할 변수
        int cmdIdx = 0;
        while (cmdIdx != cmdArr.size()) {
            String cur = cmdArr.get(cmdIdx);

            if (cur.equals("L")) {
                // 0일 때는 -1로 가지 않도록
                curSor = Math.max(0, curSor - 1);
            } else if (cur.equals("D")) {
                // 가장 맨 끝일 때는 그 이상 넘어가지 않도록
                curSor = Math.min(sb.length(), curSor + 1);
            } else if (cur.equals("B")) {
                // 커서가 맨 앞일 때는 지울게 없으므로  continue
                if (curSor == 0) {
                    cmdIdx++;
                    continue;
                }
                // 해당 위치의 문자 삭제 후 커서 재조정
                sb.delete(curSor - 1, curSor);
                curSor = Math.max(0, curSor - 1);
            } else if (cur.equals("P")) {
                String s = cmdArr.get(++cmdIdx);
                sb.insert(curSor, s);
                curSor += 1;
            }

            cmdIdx++;
        }

        return sb.toString();
    }

    public static void main(String[] args) {
        // test code
        System.out.println(solution("aba", "L B"));
        System.out.println(solution("abcd", "P x L P y"));
        System.out.println(solution("abc", "L L L P x L B P y"));
        System.out.println(solution("a", "B B L L D D P a P b P c"));
    }
}

practice4

practice4 문제

Practice4
===

문제 설명
---
특수 작전을 위해 상대방의 PC에 키보드 입력 내용을 얻을 수 있는 키로깅 프로그램을 설치했다.

해당 키로깅 프로그램으로부터는 아래와 같이 특정 값으로 내용이 수신된다.
* 8 : Backspace
* 16 : Shift
* 20 : Caps Lock
* 32 : Space bar
* 37 : 키보드 왼쪽 화살표
* 39 : 키보드 오른쪽 화살표
* 155: Insert
* 127: Delete
* 97~122: 알파벳 소문자 (기본 입력은 소문자 기준, Shift 나 Caps Lock 에 의해 변경)
* 48~57: 숫자 0~9

(이 외의 값은 들어오지 않는다고 가정)

키로깅 프로그램으로부터 수신된 데이터를 원래 내용으로 복구하는 프로그램을 작성하세요.


입출력 예시
---
|수신 내용|결과|
|---|---|
|16, 106, 101, 108, 108, 111, 37, 37, 37, 37, 37, 155, 16, 104|"Hello"|
|20, 104, 16, 105, 32, 20, 16, 106, 97, 118, 97|"Hi Java"|
|49 51 8 50 51 53 55 37 37 127 127 52 53|"12345"|
|20 65 66 16 67 16 68 49 50 51|"ABcd!@#|

practice4 답

public class Practice4 {
    public static String solution(int[] keyLog) {
        final int BACK_SPACE = 8;
        final int SHIFT = 16;
        final int CAPS_LOCK = 20;
        final int SPACE_BAR = 32;
        final int KEY_LEFT = 37;
        final int KEY_RIGHT = 39;
        final int INSERT = 155;
        final int DELETE = 127;

        StringBuffer sb = new StringBuffer();

        int step = (int)('a' - 'A');

        int curSor = 0;
        int cmdIdx = 0;
        boolean isShift = false;
        boolean isCapsLock = false;
        boolean isInsert = false;
        while (cmdIdx != keyLog.length) {
            int cur = keyLog[cmdIdx];
            
            // backspace 는 이전과 동일
            if (cur == BACK_SPACE) {
                if (curSor == 0) {
                    cmdIdx++;
                    continue;
                }
                sb.delete(curSor - 1, curSor);
                curSor = Math.max(0, curSor - 1);
            } else if (cur == SHIFT) {  // shift 입력은 해당 변수 true 로 변경
                isShift = true;
            } else if (cur == CAPS_LOCK) {  // CapsLock 은 한 번 누르면 지속 (토글)
                isCapsLock = !isCapsLock;
            } else if (cur == SPACE_BAR) {
                inputData(sb, ' ', curSor, isInsert);   // 공백 문자 입력 후 커서 증가
                curSor += 1;
            } else if (cur == KEY_LEFT) {
                curSor = Math.max(0, curSor - 1);
            } else if (cur == KEY_RIGHT) {
                curSor = Math.min(sb.length(), curSor + 1);
            } else if (cur == INSERT) { // Insert 는 한 번 누르면 지속 (토글)
                isInsert = !isInsert;
            } else if (cur == DELETE) { // Delete 는 backspace 와 커서 부분 살짝 다름
                if (curSor == sb.length()) {
                    cmdIdx++;
                    continue;
                }
                sb.delete(curSor, curSor + 1);
            } else if (cur >= 97 && cur <= 122) { // 알파벳 입력 부분
                int data = cur;
                // CapLock 켜진 상태에서 Shift 누르면 다시 소문자
                if (isCapsLock && isShift) {
                    data = cur;
                } else if (isCapsLock || isShift) { // 둘 중 하나가 true 면 대문자로 변경
                    data -= step;
                }
                inputData(sb, (char)data, curSor, isInsert);
                isShift = false;
                curSor += 1;
            } else if (cur >= 48 && cur <= 57) {
                if (isShift) {
                    // 각 숫자에 대응하는 특수문자 배열 (인덱스 0 부터 시작 -> ')')
                    char[] specialKey = {')', '!', '@', '#', '$', '%', '^', '&', '*', '('};
                    inputData(sb, specialKey[cur - '0'], curSor, isInsert);
                } else {
                    inputData(sb, (char)cur, curSor, isInsert);
                }
                isShift = false;
                curSor += 1;
            }

            cmdIdx++;
        }

        return sb.toString();
    }

    public static void inputData(StringBuffer sb, char data, int curSor, boolean isInsert) {
        // Insert 가 false 면 해당 위치에 삽입 true 면 해당 위치 변경
        if (isInsert == false) {
            sb.insert(curSor, data);
        } else {
            sb.setCharAt(curSor, data);
        }
    }


    public static void main(String[] args) {
        // Test code
        int[] keyLog = {16, 106, 101, 108, 108, 111, 37, 37, 37, 37, 37, 155, 16, 104};
        System.out.println(solution(keyLog));

        keyLog = new int[]{20, 104, 16, 105, 32, 20, 16, 106, 97, 118, 97};
        System.out.println(solution(keyLog));

        keyLog = new int[]{49, 51, 8, 50, 51, 53, 55, 37, 37, 127, 127, 52, 53};
        System.out.println(solution(keyLog));

        keyLog = new int[]{20, 97, 98, 16, 99, 16, 100, 16, 49, 16, 50, 16, 51};
        System.out.println(solution(keyLog));
    }
}

practice5

practice5 문제

Practice5
===

문제 설명
---

N 명의 아이들이 한 줄로 서있다.  
각각의 아이들은 점수 표를 가지고 있는데 점수 표에 따라 다음과 같은 규칙으로 사탕을 나누어 줘야 한다.

* 적어도 1개 이상의 사탕을 나누어줘야 한다.
* 점수가 높은 아이에게는 바로 옆의 아이 보다는 사탕을 많이 줘야 한다.

N 명의 아이들에 대한 점수 표가 ratings 배열에 주어질 때,  
나누어 줘야하는 최소한의 사탕 개수를 출력하세요.

입출력 예시
---

|입력|출력|
|---|---|
|1 2 3|6|
|3 2 1|6|
|1 0 2|5|
|1 2 2|4|
|1, 3, 5, 3, 1, 3, 5, 7, 5, 3, 1, 0|29|

practice5 답

public class Practice5 {
    public static int solution(int[] ratings) {
        if (ratings == null || ratings.length == 0) {
            return 0;
        }

        int result = 1;
        int upCnt = 1;
        int downCnt = 0;
        int peak = 0;
        for (int i = 1; i < ratings.length; i++) {
            // 다음 순번의 rating 이 더 높은 경우, upCnt 증가, peak 갱신, downCnt 쪽은 0으로 초기화
            if (ratings[i] > ratings[i - 1]) {
                upCnt++;
                peak = upCnt;
                downCnt = 0;
                result += upCnt;
            } else if (ratings[i] == ratings[i - 1]) {
                // 다음 순번과 rating 이 같은 경우는 1 개 주면 됨
                // upCnt 는 1로, downCnt 와 peak 는 0으로 초기화
                upCnt = 1;
                downCnt = 0;
                peak = 0;
                result += 1;
            } else {
                // 다음 순번의 rating 이 낮은 경우, downCnt 증가, upCnt 쪽은 1로 초기화
                downCnt++;
                upCnt = 1;
                result += downCnt;
                // rating 이 낮은 쪽으로 진행되다가 앞의 peak 를 넘어선 경우 1 씩 더해줌
                if (peak <= downCnt) {
                    result += 1;
                }
            }
        }

        return result;
    }

    public static void main(String[] args) {
        // Test code
        int[] ratings = {1, 2, 3};
        System.out.println(solution(ratings));

        ratings = new int[]{3, 2, 1};
        System.out.println(solution(ratings));

        ratings = new int[]{1, 0, 2};
        System.out.println(solution(ratings));

        ratings = new int[]{1, 2, 2};
        System.out.println(solution(ratings));

        ratings = new int[]{1, 3, 5, 3, 1, 3, 5, 7, 5, 3, 1, 0};
        System.out.println(solution(ratings));
    }
}

 

practice③

practice1

practice1 문제

Practice1
===

문제 설명
---

정수형 오름차순 데이터가 nums 라는 배열에 주어졌다.  
현재 배열 내에는 중복된 데이터들이 들어있을 수 있는데 해당 중복들을 제거하는 프로그램을 작성하세요.

이 때, 추가 배열을 사용하지 않고 중복 데이터들을 제거해야 하며  
nums 배열 하나 만 사용하여 중복 데이터를 제거 후  
정렬된 데이터를 출력하세요.


입출력 예시
---
|입력|출력|
|---|---|
|1, 1, 2|1, 2|
|0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4|0, 1, 2, 3, 4|

practice1 답

public class Practice1 {
    public static void solution(int[] nums) {
        int idx = 0;
        for (int num : nums) {
            // 정렬되어 있는 배열이므로 idx 가 0일 때와, 이전 값보다 클 때만 nums 에 업데이트
            if (idx == 0 || num > nums[idx - 1]) {
                nums[idx++] = num;
            }
        }

        System.out.print("[" + idx + "] ");
        for (int i = 0; i < idx; i++) {
            System.out.print(nums[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // Test code
        solution(new int[] {1, 1, 2});
        solution(new int[] {0, 0, 1, 1, 1, 2, 2, 3, 3, 4});
    }
}

practice2

practice2 문제

Practice2
===

문제 설명
---

주어진 nums 배열에서 두 번 나타나는 모든 정수의 배열을 반환하는 프로그램을 작성하세요.  
* nums 배열은 [1, n] 범위의 정수로 이루어져 있다.
* 각 정수는 한 번 또는 두 번 나타날 수 있다.


반환을 위한 메모리 공간 외에 추가 적인 배열 사용은 하지 않는다.


입출력 예시
---
|입력|출력|
|---|---|
|4, 3, 2, 7, 8, 2, 3, 1|2, 3|
|1, 1, 2|1|
|1, 3, 1, 3, 5, 5|1, 3, 5|

practice2 답

import java.util.ArrayList;

public class Practice2 {
    public static ArrayList<Integer> solution(int[] nums) {
        ArrayList<Integer> list = new ArrayList<>();
        
        // [1, n]의 범위로 이루어져 있는 것과 최대 2번 까지 나타날 수 있는 것을 이용
        // 각 원소의 값을 인덱스 삼아 해당 위치의 값에 부호처리를 하면
        // 같은 값이 있는지 여부를 체크할 수 있음
        for (int i = 0; i < nums.length; i++) {
            int index = Math.abs(nums[i]) - 1;

            if (nums[index] < 0) {
                list.add(Math.abs(index + 1));
            }

            nums[index] = -nums[index];
        }
        return list;
    }

    public static void main(String[] args) {
        // Test code
        int[] nums = {4, 3, 2, 7, 8, 2, 3, 1};
        System.out.println(solution(nums));

        nums = new int[]{1, 1, 2};
        System.out.println(solution(nums));

        nums = new int[]{1, 3, 1, 3, 5, 5};
        System.out.println(solution(nums));
    }
}

practice3

practice3 문제

Practice3
===

문제 설명
---

정렬된 정수형 배열 arr 이 주어졌을 때, 다음을 구하는 프로그램을 작성하세요.
* arr 과 함께 k 와 x 가 주어진다.
* k 는 개수, x 는 기준 값이다.
* x 와 절대 값 차이 기준으로 가까운 수를 k 개수 만큼 정렬된 순서로 출력하세요.
* 절대 값 차이가 같을 때는 숫자가 작은 것이 먼저 출력되도록 한다.


입출력 예시
---
|입력|k|x|출력|
|---|---|---|---|
|1, 2, 3, 4, 5|4|3|1, 2, 3, 4|
|1, 2, 3, 4, 5, 6, 7, 8, 9, 10|5|5|3, 4, 5, 6, 7|
|2, 4|1|3|2|
|2, 4|3|3|2, 4|

practice3 답

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;

public class Practice3 {
    public static void solution(int[] arr, int k, int x) {
        HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();

        // 해시 맵에 차이 값을 키로, 해당 숫자들은 값으로 리스트 형태로 뒤로 이어줌
        // 이 때, 작은 숫자들이 앞쪽에 오도록 정렬하여 추가
        for (int i = 0; i < arr.length; i++) {
            int diff = Math.abs(x - arr[i]);

            ArrayList<Integer> cur = map.get(diff);
            if (cur == null) {
                map.put(diff, new ArrayList<>(Arrays.asList(arr[i])));
            } else {
                int idx = cur.size();
                for (int j = 0; j < cur.size(); j++) {
                    if (cur.get(j) > arr[i]) {
                        idx = j;
                        break;
                    }
                }
                cur.add(idx, arr[i]);
            }
        }

        // 해시 맵에서 작은 diff 순으로 꺼내서 k 개 만큼 결과 쌓일 때 까지 반복
        ArrayList<Integer> result = new ArrayList<>();
        int cnt = 0;
        while (map.size() > 0) {
            // 최소 값 구하기 예시
            int minDiff = map.keySet().stream().min((a, b) -> a - b).get();
            ArrayList<Integer> cur = map.get(minDiff);
            map.remove(minDiff);    // 꺼낸 후에는 map 에서 삭제
            

            while (cur.size() > 0) {    // k 개 만큼 출력하기 전에 데이터가 소진될 수도 있음
                result.add(cur.get(0));
                cur.remove(0);  // 꺼낸 숫자는 리스트에서 삭제
                cnt++;

                if (cnt == k) {
                    break;
                }
            }

            if (cnt == k) {
                break;
            }
        }

        Collections.sort(result);   // 정렬 예시
        System.out.println(result);
    }

    public static void main(String[] args) {
        // Test code
        int[] arr = {1, 2, 3, 4, 5};
        solution(arr, 4, 3);

        arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        solution(arr, 5, 5);

        arr = new int[]{2, 4};
        solution(arr, 1, 3);

        arr = new int[]{2, 4};
        solution(arr, 3, 3);
    }
}

practice4

practice4 문제

Practice4
===

문제 설명
---

MxN 행렬 정보가 2차원 정수형 배열 matrix 에 주어지면  
아래 그림과 같이 나선형 모양으로 출력하는 프로그램을 작성하세요.

![img_1.png](../imgs/img_1.png)

입출력 예시
---
|입력|출력|
|---|---|
|{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}|1, 2, 3, 6, 9, 8, 7, 4, 5|
|{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10 ,11 ,12}}|1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7|

practice4 답

import java.util.ArrayList;

public class Practice4 {
    public static ArrayList<Integer> solution(int[][] matrix) {
        if (matrix == null || matrix.length == 0) {
            return null;
        }

        ArrayList<Integer> result = new ArrayList<>();
        int rowStart = 0;
        int rowEnd = matrix.length - 1;
        int colStart = 0;
        int colEnd = matrix[0].length - 1;

        while (rowStart <= rowEnd && colStart <= colEnd) {
            // 오른쪽 방향 이동
            for (int i = colStart; i <= colEnd; i++) {
                result.add(matrix[rowStart][i]);
            }
            rowStart++;

            // 아래쪽 방향 이동
            for (int i = rowStart; i <= rowEnd; i++) {
                result.add(matrix[i][colEnd]);
            }
            colEnd--;
            
            // 왼쪽 방향 이동
            if (rowStart <= rowEnd) {
                for (int i = colEnd; i >= colStart; i--) {
                    result.add(matrix[rowEnd][i]);
                }
            }
            rowEnd--;
            
            // 위쪽 방향 이동
            if (colStart <= colEnd) {
                for (int i = rowEnd; i >= rowStart; i--) {
                    result.add(matrix[i][colStart]);
                }
            }
            colStart ++;
        }

        return result;
    }
    
    public static void main(String[] args) {
        // Test code
        int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        System.out.println((solution(matrix)));

        matrix = new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10 ,11 ,12}};
        System.out.println((solution(matrix)));
    }
}

practice5

practice5 문제

Practice5
===

문제 설명
---
n개의 정수형 데이터가 height 배열에 주어졌다.  
height 배열의 각각의 원소는 아래 그림과 같이 각 벽에 대한 높이를 의미한다.

이와 같이 높이 값들이 주어졌을 때,  
벽 사이사이의 빈 공간에 담을 수 있는 물의 총량을 출력하세요.

![img_1.png](../imgs/img_2.png)

입출력 예시
---
|입력|출력|
|---|---|
|0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1|6|
|4, 2, 0, 3, 2, 5|9|

practice5 답

public class Practice5 {
    public static int solution(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        }

        // 좌, 우 인덱스 설정
        int left = 0;
        int right = height.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        int result = 0;

        while (left < right) {
            if (height[left] < height[right]) { // 왼쪽 벽이 낮은 경우
                if (height[left] >= leftMax) { // 이전의 왼쪽 최대 높이 벽보다 더 큰 경우,
                    leftMax = height[left];     // 물이 담기진 않고 벽 높이 갱신
                } else {
                    result += leftMax - height[left];   // 그 외의 경우는 높이 줄어든 만큼 물이 담김
                }
                left++;
            } else {    // 오른쪽 벽이 낮은 경우
                if (height[right] >= rightMax) {
                    rightMax = height[right];
                } else {
                    result += rightMax - height[right];
                }
                right--;
            }
        }
        return result;
    }
    
    public static void main(String[] args) {
        // Test code
        int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
        System.out.println(solution(height));

        height = new int[]{4, 2, 0, 3, 2, 5};
        System.out.println(solution(height));
    }
}

'공부 > JAVA' 카테고리의 다른 글

[JAVA]JAVA 인텔리제이 설정  (0) 2024.04.27
[JAVA]스트림  (1) 2024.04.27
[JAVA]람다식  (1) 2024.04.27
Comments