240331

Regular Kim·2024년 3월 31일
0

회고

목록 보기
35/59

240331 회고 💬

봄 황사와 함께 미세먼지가 기승을 부리는 1주일이었다. 코 아프고, 목 아프고, 손도 끈적거리고,,, 🤧 가만히 있어도 수명이 깎여나가는 1주일...💀 24년 3월의 마지막 주를 회고한다.

Keep 👍

  • 알고리즘 문제 풀이를 이번 주에도 7일 연속으로 해냈다. 그리고 오프라인 알고리즘 스터디 그룹도 참가했다.
    - 알고리즘 인강 복습 진행은 회사 스터디 시간에 하려고 했다. 그런데 요즘 바빠서 회사 스터디 진행이 안 된다. 주말에 몰아서 문제 풀이를 진행했다. 저번 복습시간에는 반복문, 2차원 배열 부분을 끝냈다. 그래서 이번 복습 시간에는 해쉬, 맵 자료구조를 이용한 문제 풀이를 진행했다.
    - 팀 스파르타의 99클럽 코테 스터디에 참가했다. 혼자 코테 준비를 해온지 어언 반년... 폐관수련하는 기분이다. 혼자 공부하다보니 내가 지금 어느 정도인지 가늠할 수 없었다. 그리고 사실 쉬운 문제를 골라 푸는 요령도 없잖아 있다보니 점점 매너리즘에 빠지는 상황이었다. 그런데 매일 1문제씩 추천을 해주고 다른 사람들 풀이도 들어 볼 수 있는 시간이 생겼다. 좋은 기회라고 여기고 있다.
    - 차집합 해쉬 문제를 풀었다. 실버 4 수준 문제에는 자료 구조 문제가 많은 듯 하다. 입력 원소 개수가 많지 않기 때문에 복잡한 로직은 필요하지 않다. 해쉬 개념만 알고 있으면 쉽게 풀 수 있다. 마지막에 오름차순으로 원소 출력이 필요하다. 이 부분도 간단하게 소팅하면 된다. 해쉬 개념을 아냐 모르냐 물어보는 문제이다.
    - 세 개의 소수 문제 소수 판별 문제를 풀었다. 에라토스테네스의 채로 소수들을 구한 다음 브루트 포스로 목푯값을 찾으면 되는 문제다. 역할별로 클래스를 나누느라 시간이 좀 걸렸다.
    - 지뢰 찾기 문제 설명을 이해하는데 시간이 오래 걸렸다. 역시 국어가 제일 문제다. 문제 풀이 포인트로는 일단 입력값대로 클릭을 계속 진행한다는 점이다. 그리고 만약 클릭한 위치에 지뢰가 위치한다면 지뢰 위치만 결과값에 표시해주면 된다.
    - Sort 마스터 배지훈의 후계자 문제를 풀었다. 정렬과 해쉬맵 개념이 섞인 문제다. 맵 기본 메소드를 알고 있다면 쉽게 풀 수 있는 문제다.
    - 알고리즘 인강 복습도 진행했다. 이번에 푼 문제들은 낯선 메소드를 사용해야 쉽게 풀 수 있는 문제였다. Map 의 equals() 메소드는 두 개의 map 인스턴스 키와 그 키의 값이 같은지 비교해준다. TreeSet 은 기본으로 오름차순 정렬이다. 내림차순으로 값을 얻고 싶다면 순회하는 순간에 descendingSet() 메소드를 사용하면 된다. 아니면 TreeSet 인스턴스 생성 시점에 Collections.reverseOrder() 파라미터를 넘겨주면 된다.
// 1. descendingSet() 옵션 사용
for (Integer i : deck.descendingSet()) {  
	if(idx++ + 1 == targetIdx) return i;  
}

// 2. 생성시 내림차순 옵션 추가
new TreeSet<>(Collections.reverseOrder());
  • Servlet 공부도 진행했다.
    - init() -> service() -> doGet() || doPost() 흐름으로 서블릿이 스레드를 사용하는 과정을 생명 주기를 공부하며 알아봤다. 서블릿은 인스턴스를 생성하지 않고 스레드를 생성하여 요청을 처리한다. 그러므로 클라이언트 요청에 인스턴스를 생성한다는 말은 틀린 말이다.
    - doGet() 혹은 doPost() 메소드는 인자로 HttpServletRequest, HttpServletResponse 두 가지를 받는다. 그런데 이 두 파라미터는 인터페이스이다. 인스턴스는 누가 생성할까? 바로 컨테이너가 생성한다. 개발자는 HttpServletRequest, HttpServletResponse 두 인터페이스를 구현할 일이 절대 없다. 그러니 그냥 사용만 하면 된다.
  • 매일은 아니지만 그래도 운동을 하긴 했다. 주말에는 헬스장도 다녀왔다. 이번 주에는 등운동을 진행했다.
  • 출퇴근 공부로 자바 기본 문법 복습을 하고 있다. 이번 주에는 추상 클래스, 메소드와 인터페이스, 상속, 다중 구현을 공부했다. 부끄럽지만 추상 클래스와 인터페이스의 차이점을 명쾌하게 설명하지 못하는 상태였다. 하지만 이번 공부로 자신 있게 설명할 수 있게 되었다. 또한 다중 구현을 했을 때의 메소드 호출 흐름도 공부했다.

Extras 😀

차집합

import java.io.*;  
import java.util.*;  
  
public class Main {  
  
    public static void main(String[] args) {  
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {  
  
            Input ip = getInput(br);  
            Solution s = new Solution();  
            System.out.println(s.solution(ip.arr1, ip.arr2));  
  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    private static Input getInput(BufferedReader br) throws IOException {  
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");  
        int len1 = Integer.parseInt(st.nextToken());  
        int len2 = Integer.parseInt(st.nextToken());  
  
        int[] arr1 = getArray(br, len1);  
        int[] arr2 = getArray(br, len2);  
  
        return new Input(arr1, arr2);  
    }  
  
    private static int[] getArray(BufferedReader br, int len) throws IOException {  
        int[] arr = new int[len];  
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");  
        for (int i = 0; i < arr.length; i++) {  
            arr[i] = Integer.parseInt(st.nextToken());  
        }  
        return arr;  
    }  
    static class Input{  
        int[] arr1;  
        int[] arr2;  
  
        public Input(int[] arr1, int[] arr2) {  
            this.arr1 = arr1;  
            this.arr2 = arr2;  
        }  
    }  
}  
  
class Solution {  
  
    public String solution(int[] arr1, int[] arr2) {  
        return getAnswer(getDiffer(arr1, getSet(arr2)));  
    }  
  
    private String getAnswer(List<Integer> list) {  
        StringBuilder answer = new StringBuilder();  
        if(list.isEmpty()) return "0";  
  
        answer.append(list.size()).append("\n");  
  
        for (int i : list) {  
            answer.append(i).append(" ");  
        }  
        return answer.toString();  
    }  
  
    private List<Integer> getDiffer(int[] arr1, Set<Integer> set) {  
        List<Integer> result = new ArrayList<>();  
  
        for (int i : arr1) {  
            if(!set.contains(i)) result.add(i);  
        }  
        Collections.sort(result);  
        return result;  
    }  
  
    private Set<Integer> getSet(int[] arr) {  
        Set<Integer> set = new HashSet<>();  
        for (int i : arr) {  
            set.add(i);  
        }  
        return set;  
    }  
}

세 개의 소수 문제

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.ArrayList;  
import java.util.Arrays;  
import java.util.List;  
  
public class Main {  
  
    public static void main(String[] args) {  
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {  
  
            Solution s = new Solution();  
            System.out.println(s.solution(getInput(br)));  
  
        } catch (IOException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    private static int[] getInput(BufferedReader br) throws IOException {  
        int len = Integer.parseInt(br.readLine());  
  
        int[] arr = new int[len];  
        for (int i = 0; i < arr.length; i++) {  
            arr[i] = Integer.parseInt(br.readLine());  
        }  
  
        return arr;  
    }  
}  
  
class Solution {  
  
    public String solution(int[] arr) {  
        return getAnswer(arr);  
    }  
  
    private String getAnswer(int[] arr) {  
        StringBuilder answer = new StringBuilder();  
        for (int i : arr) {  
            Sieve sieve = new Sieve(i);  
            ThreePrimeProblemSolver tpps = new ThreePrimeProblemSolver(i, sieve.getPrimeNums());  
            int[] result = tpps.solveThreePrimeProblem();  
            if (isSolved(result)) {  
                for (int primeNum : result) {  
                    answer.append(primeNum).append(" ");  
                }  
                answer.append("\n");  
            }  
        }  
        return answer.toString();  
    }  
  
    private boolean isSolved(int[] result) {  
        int sum = 0;  
        for (int i : result) {  
            sum += i;  
        }  
  
        return sum != 0;  
    }  
}  
  
class ThreePrimeProblemSolver {  
  
    int target;  
    List<Integer> sievedNums;  
  
    public ThreePrimeProblemSolver(int target, List<Integer> sievedNums) {  
        this.target = target;  
        this.sievedNums = sievedNums;  
    }  
  
    public int[] solveThreePrimeProblem() {  
        for (Integer sievedNum1 : this.sievedNums) {  
            for (Integer sievedNum2 : this.sievedNums) {  
                for (Integer sievedNum3 : this.sievedNums) {  
                    if(sievedNum1 + sievedNum2 + sievedNum3 == this.target)  
                        return new int[]{sievedNum1, sievedNum2, sievedNum3};  
                }  
            }  
        }  
        return new int[]{0, 0, 0};  
    }  
}  
  
class Sieve {  
  
    boolean[] sieve;  
  
    List<Integer> primeNums;  
  
    public Sieve(int limit) {  
        this.sieve = new boolean[limit + 1];  
        Arrays.fill(this.sieve, true);  
        this.primeNums = getSievedNums();  
    }  
  
    private List<Integer> getSievedNums() {  
        List<Integer> sievedNums = new ArrayList<>();  
  
        for (int i = 2; i < this.sieve.length; i++) {  
            if (this.sieve[i]) {  
                sievedNums.add(i);  
                sieveNums(i);  
            }  
        }  
        return sievedNums;  
    }  
  
    private void sieveNums(int num) {  
        for (int i = num * 2; i < this.sieve.length; i += num) {  
            this.sieve[i] = false;  
        }  
    }  
  
    public List<Integer> getPrimeNums() {  
        return this.primeNums;  
    }  
}

지뢰 찾기


import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            int len = Integer.parseInt(br.readLine());
            Solution s = new Solution();
            System.out.println(s.solution(getInput(br, len), getInput(br, len)));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static String[][] getInput(BufferedReader br, int len) throws IOException {
        String[][] board = new String[len][len];

        for (int i = 0; i < board.length; i++) {
            board[i] = br.readLine().split("");
        }

        return board;
    }
}

class Solution {

    public String solution(String[][] board, String[][] input) {
        MineSearchPlayer msp = new MineSearchPlayer(board, input);
        return getAnswer(msp.getResult());
    }

    private String getAnswer(String[][] result) {
        StringBuilder answer = new StringBuilder();

        for (String[] row : result) {
            for (String i : row) {
                answer.append(i);
            }
            answer.append("\n");
        }
        return answer.toString();
    }

    private class MineSearchPlayer {

        String[][] mineField;
        String[][] inputs;
        boolean[][] isVisited;
        int[][] result;
        String[][] processedField;

        boolean isAlreadyFail = false;

        int[][] directions = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}};

        public MineSearchPlayer(String[][] mineField, String[][] inputs) {
            this.mineField = mineField;
            this.inputs = inputs;
            this.isVisited = new boolean[mineField.length][mineField[0].length];
            this.result = new int[mineField.length][mineField[0].length];
            this.processedField = new String[mineField.length][mineField[0].length];
            for (String[] strings : this.processedField) {
                Arrays.fill(strings, ".");
            }
        }

        public String[][] getResult() {
            playMineSearch();
            return afterPlay();
        }

        private String[][] afterPlay() {
            for (int x = 0; x < this.result.length; x++) {
                for (int y = 0; y < this.result[x].length; y++) {
                    if (this.isVisited[x][y])this.processedField[x][y] = String.valueOf(this.result[x][y]);
                }
            }

            if(this.isAlreadyFail) failProcess();

            return this.processedField;
        }

        private void playMineSearch() {
            for (int x = 0; x < this.inputs.length; x++) {
                for (int y = 0; y < this.inputs[x].length; y++) {
                    if("x".equals(this.inputs[x][y])){
                        search(x, y);
                    }
                }
            }
        }

        private void search(int x, int y) {
            this.isVisited[x][y] = true;
            if (isMineLocated(x, y) && !this.isAlreadyFail) {
                this.isAlreadyFail = true;
            }
            for (int[] direction : this.directions) {
                int nx = x + direction[0];
                int ny = y + direction[1];
                if (isWithinMineField(nx, ny) && isMineLocated(nx, ny)) this.result[x][y]++;
            }
        }

        private boolean isWithinMineField(int x, int y) {
            return 0 <= x && x < this.inputs.length && 0 <= y && y < this.inputs[x].length;
        }

        private boolean isMineLocated(int x, int y) {
            return "*".equals(this.mineField[x][y]);
        }

        private void failProcess() {
            for (int x = 0; x < this.processedField.length; x++) {
                for (int y = 0; y < this.processedField[x].length; y++) {
                    if("*".equals(this.mineField[x][y])) this.processedField[x][y] = "*";
                }
            }
        }
    }
}


profile
What doesn't kill you, makes you stronger

0개의 댓글