h2 database는 매우 작고 빠른 데이터베이스이다. 파일이나 서버형식부터 메모리 형식으로 데이터를 저장할 수 있으며 데이터베이스의 크기도 매우 작아서 간단히 테스트를 진행할 때 사용하기 편리하다. h2 database 홈페이지는 아래 링크를 통해 방문할 수 있다.

https://www.h2database.com/html/main.html

 

홈페이지를 방문하면 Windows 인스톨 버전과 모든 OS에서 사용가능한 java 파일이 존재한다.

맥 환경이라 All Platforms를 클릭하여 설치했다. 윈도우에서도 인스톨러를 설치하거나 All Platforms를 사용할 수 있다. All Platforms를 클릭하여 압축해제하고 들어가서 bin 폴더를 보면 h2.sh 파일이 존재한다. (윈도우는 h2.bat)

윈도우의 경우 관리자모드로 cmd를 실행한 후에 h2.bat 을 실행하면 되고, 맥이나 리눅스 환경은 권한설정을 해주어야 한다. 

chmod 755 h2.sh 명령어를 이용해 권한설정을 한 후 실행하면 웹콘솔 화면이 뜨게 된다. 

이 창이 뜨지 않거나 연결버튼 클릭 시 오류가 발생한다면 url 주소를 본인의 IP에서 localhost로 변경해준 후 재접속하면 된다.

이 상태에서 연결 시험 버튼을 누르면 오류가 발생하면서 작동하지 않을 수 있는데, 그 이유가 데이터베이스가 될 파일이 존재하지 않아서 그렇다. 따라서 JDBC URL 부분을 jdbc:h2:~/test 로 변경한 후 연결버튼을 누르게 되면 접속이 됨과 동시에 test.mv.db 파일이 생성된다. 맥 기준으로는 ~/ 에 test 파일을 설치 했으므로 해당 위치에 저장되며 윈도우는 ~/ 위치가 어디인지는 모르겠으나, 파일이 저장되었을 것이다. 그리고 다시 JDBC URL에 jdbc:h2:tcp://localhost/~/test 를 입력한 후 연결시험을 누르면 시험 성공 메시지가 출력되며 연결 버튼을 클릭해 접속할 수 있다.

 

해당 문제를 푸는데 좀 많은 시간이 소요되었다. 먼저 문제를 살펴보면 아래와 같다.

 

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을 따라 1cm × 1cm의 정사각형으로 잘라 사용할 예정이었는데, 누군가가 이 종이를 대각선 꼭지점 2개를 잇는 방향으로 잘라 놓았습니다. 그러므로 현재 직사각형 종이는 크기가 같은 직각삼각형 2개로 나누어진 상태입니다. 새로운 종이를 구할 수 없는 상태이기 때문에, 이 종이에서 원래 종이의 가로, 세로 방향과 평행하게 1cm × 1cm로 잘라 사용할 수 있는 만큼만 사용하기로 하였습니다.
가로의 길이 W와 세로의 길이 H가 주어질 때, 사용할 수 있는 정사각형의 개수를 구하는 solution 함수를 완성해 주세요.

제한사항
  • W, H : 1억 이하의 자연수

즉, 8 x 12에서 흰색칸을 모두 지운 80이라는 값이 반환이 되어야 한다.

먼저 아래처럼 패턴을 나누었다. 패턴을 나누는 기준은 연속되지 않은 흰색 칸을 기준으로 했다.

그럼 패턴이 총 4개가 나오게 된다. 패턴의 길이는 가로 2, 세로 3인데, 이 값들은 가로와 세로를 각각 4로 나눈값이 된다. 하나 더 예시로 작성해 보았다. 

사용 못하는 칸이 모두 연속되어 있으므로 패턴이 1개이고 패턴의 길이는 가로 4, 세로 3이 된다. 패턴의 길이와 총 길이가 같으므로 패턴의 가로와 세로는 각각 1로 나눈 값과 동일하다. 이렇게 5x3, 6x4 등등의 길이의 종이를 위와 같은 방법으로 구해보았다. 

 

그 결과, 각 패턴의 길이는 종이의 가로, 세로값을 최대공약수로 나눈 값이 되며 패턴의 개수는 최대공약수의 값과 동일하다는 결론이 나왔다. 다시 위에 문제로 돌아가 패턴을 살펴보면,

패턴의 가로는 2, 세로는 3이 되는데 여기서 사용할 수 없는 칸은 총 4칸이다. 이 값 또한 가로와 세로를 더한 후 -1을 해주면 된다. 그 이유는 아래와 같다.

그림에서 볼 수 있듯이 3번을 위로, 4번을 왼쪽으로 붙이게 되면 패턴의 가로 + 세로 - 1 이 되기 때문에 사용하지 못하는 개수는 총 4개이다. 위에서 4x3 패턴의 예시도 동일하게 아래 그림처럼 가능하다. 

3, 5번을 왼쪽으로 붙이고 4, 6번을 위로 붙이게 되면 4 + 3 - 1 만큼의 개수를 사용하지 못하게 된다. 

위 내용을 코드로 작성하여 제출했다.

https://github.com/banjjak2/Programmers/blob/main/Level2/%EB%A9%80%EC%A9%A1%ED%95%9C_%EC%82%AC%EA%B0%81%ED%98%95.java

class Solution {
    public long solution(int w, int h) {
        long answer = 0;
        long totalCount = (long)w * h;
        // 패턴 총 개수
        int patternCount = gcd(w, h);

        // 1패턴당 가로 개수
        int widthPerPattern = w / patternCount;
        // 1패턴당 세로 개수
        int heightPerPattern = h / patternCount;
        // 1패턴당 못쓰는 개수
        int unusedCountPerPattern = widthPerPattern + heightPerPattern - 1;

        // 총개수 - (1패턴당 못쓰는 개수 * 패턴 총 개수);
        answer = totalCount - (unusedCountPerPattern * patternCount);
        return answer;
    }

    // 최대공약수 구하기
    public int gcd(int n, int m){
        // 나머지가 0이면
        if (m == 0){
            // 나눈값 반환
            return n;
        }

        // 나눈 수, 나머지 값
        return gcd(m, n % m);
    }
}

[Level 2] 단체사진 찍기 (Java)


프로그래머스의 Level2 문제인 단체사진 찍기를 풀었다. 나같은 경우 해당 문제를 아래와 같이 풀었었다.

  1. 알파벳 8자리에서 나올 수 있는 모든 경우의 수를 모두 구한다. (8! = 40320)
  2. 구한 경우의 수들을 조건에 맞는지 확인 후 조건에 만족할 경우 +1 해준다.
import java.util.*;

public class 단체사진_찍기 {
    public static void main(String[] args) {
        int n = 0;
        // String[] data = {
        //     "N~F=0", 
        //     "R~T>2"
        // };

        String[] data = {
            "M~C<2", 
            "C~M>1"
        };

        System.out.println(solution(n, data));
    }

    
    static char[] friendsAlphabet = new char[] { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
    public static int solution(int n, String[] data){
        int answer = 0;
        createAllFriendsRow(0);
        for (String cs : createFriendsRowList) {
            if (checkCondition(cs, data)){
                answer++;
            }
        }
        return answer;
    }

    static boolean[] visited = new boolean[8];
    static List<String> createFriendsRowList = new ArrayList<String>();
    static char[] createFriendsRowArray = new char[8];
    public static void createAllFriendsRow(int index){
        if (index == visited.length){
            createFriendsRowList.add(String.valueOf(createFriendsRowArray));
        }
        else{
            for(int i=0; i<visited.length; i++){
                if (!visited[i]){
                    visited[i] = true;
                    createFriendsRowArray[index] = friendsAlphabet[i];
                    createAllFriendsRow(index + 1);
                    visited[i] = false;
                }
            }
        }
    }

    public static boolean checkCondition(String friendsArray, String[] data){
        String[] splits;
        String startFriend, endFriend;
        String condition;
        int conditionCount = 0;
        int gap;
        int indexGap = 0;
        int endIndex, startIndex;

        for (String c : data) {
            splits = c.split("");

            startFriend = splits[0];
            endFriend = splits[2];
            condition = splits[3];
            gap = Integer.parseInt(splits[4]);

            startIndex = friendsArray.indexOf(startFriend);
            endIndex = friendsArray.indexOf(endFriend);
            indexGap = Math.abs(endIndex - startIndex) - 1;

            switch (condition) {
                case "=":
                    if (indexGap != gap){
                        return false;
                    }
                    conditionCount++;
                    break;
                
                case ">":
                    if (indexGap <= gap){
                        return false;
                    }
                    conditionCount++;
                    break;

                case "<":
                    if (indexGap >= gap){
                        return false;
                    }
                    conditionCount++;
                    break;
            }
        }

        if (conditionCount == data.length){
            return true;
        }
        else{
            return false;
        }
    }
}

그 결과...

8.6초라는 어마어마한 성능을 가지고 있었다;

8! 만큼 2번 (프렌즈의 모든 경우의 수 구할 때, 조건에 맞는지 구할 때)을 돌아서 성능이 저렇게 나온건지 해서 아래와 같이 수정했었다.

  1. 모든 경우의 수를 구함과 동시에 조건에 맞는지 확인한다.
  2. 조건에 맞다면 +1 해준다.

위와 같이 작성해봐도 동일하게 8초 이상이 출력되었다. 그래서 다시 확인한 결과 checkCondition 함수에서 split 메소드로 문자열을 자르는 부분이 있었는데, 이 부분을 split 대신 charAt 메소드를 사용하여 구현해 보았다.

class Solution {
    char[] friendsAlphabet = new char[] { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
    public int solution(int n, String[] data){
        int answer = 0;
        createAllFriendsRow(0, data);
        answer = correctCount;
        return answer;
    }

    boolean[] visited = new boolean[8];
    char[] createFriendsRowArray = new char[8];
    int correctCount = 0;
    public void createAllFriendsRow(int index, String[] data){
        if (index == visited.length){
            if (checkCondition(String.valueOf(createFriendsRowArray), data)){
                correctCount++;
            }
        }
        else{
            for(int i=0; i<visited.length; i++){
                if (!visited[i]){
                    visited[i] = true;
                    createFriendsRowArray[index] = friendsAlphabet[i];
                    createAllFriendsRow(index + 1, data);
                    visited[i] = false;
                }
            }
        }
    }

    public boolean checkCondition(String friendsArray, String[] data){
        char startFriend, endFriend;
        char condition;
        int conditionCount = 0;
        int gap;
        int indexGap = 0;
        int endIndex, startIndex;

        for (String c : data) {
            startFriend = c.charAt(0);
            endFriend = c.charAt(2);
            condition = c.charAt(3);
            gap = c.charAt(4) - '0';

            startIndex = friendsArray.indexOf(startFriend);
            endIndex = friendsArray.indexOf(endFriend);
            indexGap = Math.abs(endIndex - startIndex) - 1;

            switch (condition) {
                case '=':
                    if (indexGap != gap){
                        return false;
                    }
                    conditionCount++;
                    break;
                
                case '>':
                    if (indexGap <= gap){
                        return false;
                    }
                    conditionCount++;
                    break;

                case '<':
                    if (indexGap >= gap){
                        return false;
                    }
                    conditionCount++;
                    break;
            }
        }

        if (conditionCount == data.length){
            return true;
        }
        else{
            return false;
        }
    }
}

위와 같이 작성 한 후 다시 제출했더니 아래와 같은 결과가 나왔다.

 

속도와 메모리가 9배 이상 차이가 남을 확인할 수 있었다. 

 

결론.

  - split 대신 charAt을 사용할 수 있는 경우 charAt을 사용하는 것이 성능상에 유리하다. 

# Programmers

알고리즘 문제풀이

 

# LEVEL 1

신규아이디추천 (21. 07. 13)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%8B%A0%EA%B7%9C%EC%95%84%EC%9D%B4%EB%94%94%EC%B6%94%EC%B2%9C.java

- 정규표현식 이용해서 각 스텝별로 구현

(https://banjjak1.tistory.com/8)

 

------------------------------------------------------------------------------------------

 

키패드누르기 (21. 07. 18)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%82%A4%ED%8C%A8%EB%93%9C%EB%88%84%EB%A5%B4%EA%B8%B0.java

- 키패드 위치를 class로 추출하여 관리 및 알기 쉽게 작성

- 두 점 사이의 거리 구하기 공식을 이용하여 최단거리 구현

(https://banjjak1.tistory.com/9)

 

------------------------------------------------------------------------------------------

 

음양더하기 (21. 07. 25)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9D%8C%EC%96%91%EB%8D%94%ED%95%98%EA%B8%B0.java

- 음수의 경우 절대값을 취해 결과값 반환

 

------------------------------------------------------------------------------------------

 

완주하지못한선수 (21. 07. 31)

https://banjjak1.tistory.com/12

 

sort 메소드 이용 : https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80%EB%AA%BB%ED%95%9C%EC%84%A0%EC%88%98_sort.java

- Arrays.sort 메소드를 이용해 String 배열을 정렬 후 비교

- Arrays.sort 메소드에서 String 정렬 시 알파벳 순으로 정렬하기 때문



HashMap 이용 : https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80%EB%AA%BB%ED%95%9C%EC%84%A0%EC%88%98_hash.java

- sort 메소드를 이용했을 때 속도가 느려진 관계로 hash로 구현해서 테스트 진행

- HashMap을 이용하여 각 선수들의 이름을 Key로 두고 참가자라면 +1, 참가자 중 완주자라면 -1을 하여

0이 아닌 선수가 있을 경우 entrySet 메소드를 이용해 해당 (미완주자)Key 값을 반환

 

sort 메소드의 경우 내부적으로 TimSort 알고리즘을 사용하는데 Merge Sort 알고리즘을 기반으로 작성되었고,

Insertion Sort와 merge Sort 알고리즘의 결합 형태라고 한다.

HashMap의 경우 키 값을 알면 바로 Value 값을 알 수 있기 때문에 속도면에서 빠르다.

 

------------------------------------------------------------------------------------------

 

위클리챌린지_1주차 (21. 08. 03)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9C%84%ED%81%B4%EB%A6%AC%EC%B1%8C%EB%A6%B0%EC%A7%80_1%EC%A3%BC%EC%B0%A8.java

- 모자른 돈을 구하는 문제인데, 결과값이 음수가 나올 경우 모자른 돈이 되므로 *-1 을 취해 양수로 만들어 반환

 

------------------------------------------------------------------------------------------

 

위클리챌린지_2주차 (21. 08. 10)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9C%84%ED%81%B4%EB%A6%AC%EC%B1%8C%EB%A6%B0%EC%A7%80_2%EC%A3%BC%EC%B0%A8.java

- 학점을 계산하는 문제로, 유일한 값인지 판별 후 점수 계산 및 학점 계산

- String을 이용하여 단순히 연결했지만 성능상 문제가 있어 StringBuilder로 변경 후 테스트 진행

- 빈번한 문자열 연결시 StringBuilder나 StringBuffer를 이용해야 함

https://banjjak1.tistory.com/15

 

------------------------------------------------------------------------------------------

 

체육복 (21. 08. 14)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%B2%B4%EC%9C%A1%EB%B3%B5.java

- 탐욕 알고리즘을 이용한 문제 (현재 상황에서 제일 최선의 선택을 하는 알고리즘)

- 도난당한 사람의 번호와 여분을 가지고 있는 사람의 번호를 정렬

- 여벌 체육복을 가져온 학생이 도난당할 경우를 먼저 계산

- 여분 체육복을 가지고 있는 사람의 앞/뒤 번호가 도난당했는지 확인 후 계산

 

------------------------------------------------------------------------------------------

 

K번째 수 (21. 08. 14)

sort 메소드 사용 : https://github.com/banjjak2/Programmers/blob/main/Level1/K%EB%B2%88%EC%A7%B8%EC%88%98_sort%EB%A9%94%EC%86%8C%EB%93%9C%EC%9D%B4%EC%9A%A9.java

 

sort 메소드 구현 : X

 

Arrays.sort 메소드 사용 시 성능이 저하되는 문제가 있음. sort 방법을 변경해서 테스트 예정

 

------------------------------------------------------------------------------------------

 

숫자 문자열과 영단어 (21. 08. 14)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%88%AB%EC%9E%90_%EB%AC%B8%EC%9E%90%EC%97%B4%EA%B3%BC_%EC%98%81%EB%8B%A8%EC%96%B4.java

- HashMap을 이용하여 Key, Value로 문제풀이 진행

 

------------------------------------------------------------------------------------------

 

로또의 최고 순위와 최저 순위 (21. 08. 15)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%A1%9C%EB%98%90%EC%9D%98_%EC%B5%9C%EA%B3%A0_%EC%88%9C%EC%9C%84%EC%99%80_%EC%B5%9C%EC%A0%80_%EC%88%9C%EC%9C%84.java

- 전달받은 lottos 배열에서 0(알 수 없는 번호)일 경우 카운트 증가

- win_nums 배열에 있는 값이 lottos 배열에 있다면 correctCount 증가

- 최고 순위는 알 수 없는 번호 모두 당첨번호일 때 이므로 correctCount 값에 + 0일 경우의 카운트 값

- 최저 순위는 알 수 없느 번호 모두 낙첨번호일 때 이므로 correctCount 값

- correctCount 값으로 순위 반환

 

------------------------------------------------------------------------------------------

 

크레인 인형뽑기 게임 (21. 08. 16)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%81%AC%EB%A0%88%EC%9D%B8_%EC%9D%B8%ED%98%95%EB%BD%91%EA%B8%B0_%EA%B2%8C%EC%9E%84.java

- 크레인이 잡아서 뽑을 경우 Stack에 데이터 push

- 방금 뽑은 카카오 캐릭터가 제일 마지막에 뽑은 캐릭터 값과 같을 경우 pop

- 동일 캐릭터가 2개일 때 터지므로 pop 할때마다 +2씩 증가

 

------------------------------------------------------------------------------------------

 

폰켓몬 (21. 08. 16)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%8F%B0%EC%BC%93%EB%AA%AC.java

- HashSet을 이용하여 nums 중복 제거

- 중복제거한 데이터의 길이가 nums 개수의 반절보다 작을 경우 최대 선택 가능한 종류 개수이므로

중복제거한 데이터의 길이를 반환

- nums 데이터 길이의 절반이 중복제거한 데이터의 길이보다 더 클 경우 최대 선택 가능한 종류 개수가 데이터 반절의 길이이므로

데이터 반절의 길이를 반환

 

------------------------------------------------------------------------------------------

 

소수 만들기 (21. 08. 22)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%86%8C%EC%88%98_%EB%A7%8C%EB%93%A4%EA%B8%B0.java

- 조합을 이용하여 구현

 

------------------------------------------------------------------------------------------

 

모의고사 (21. 08. 24)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC.java

- 수포자 1, 2, 3이 맞은 정답 개수를 correctCount 배열에 넣고 배열 중 최대값을 구하여 동일한 값이 몇 개인지 판별 후 해당 수포자 번호 반환

 

------------------------------------------------------------------------------------------

 

<span style="color:red">실패율 (21. 08. 24) - 재풀이</span>

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%8B%A4%ED%8C%A8%EC%9C%A8.java

- HashMap을 이용해서 풀이

- 다른 풀이에 비해 속도면에서 성능이 안좋음. 원인파악 후 재풀이 예정

 

------------------------------------------------------------------------------------------

 

3진법 뒤집기 (21. 08. 25)

https://github.com/banjjak2/Programmers/blob/main/Level1/_3%EC%A7%84%EB%B2%95_%EB%92%A4%EC%A7%91%EA%B8%B0.java

- StringBuilder와 거듭제곱 기능으로 해결

 

------------------------------------------------------------------------------------------

 

두 개 뽑아서 더하기 (21. 08. 25)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%91%90_%EA%B0%9C_%EB%BD%91%EC%95%84%EC%84%9C_%EB%8D%94%ED%95%98%EA%B8%B0.java

- 조합을 이용해 해결

 

------------------------------------------------------------------------------------------

 

약수의 개수와 덧셈 (21. 08. 25)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%95%BD%EC%88%98%EC%9D%98_%EA%B0%9C%EC%88%98%EC%99%80_%EB%8D%A7%EC%85%88.java

- 약수의 개수를 구한 후 더함

 

------------------------------------------------------------------------------------------

 

예산 (21. 08. 25)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%98%88%EC%82%B0.java

- 신청금액을 sort 한 후 신청금액 배열의 앞에서부터 빼서 해결

 

------------------------------------------------------------------------------------------

 

1차 비밀지도 (21. 08. 27)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%B9%84%EB%B0%80%EC%A7%80%EB%8F%84_1%EC%B0%A8.java

- arr1과 arr2의 각 데이터들을 비트연산(OR) 후 결과값을 가지고 2진화하여 0이면 " ", 1이면 "#"으로 추가

 

------------------------------------------------------------------------------------------

 

가운데 글자 가져오기 (21. 08. 27)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EA%B0%80%EC%9A%B4%EB%8D%B0_%EA%B8%80%EC%9E%90_%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0.java

- substring 메소드 이용

 

------------------------------------------------------------------------------------------

 

다트게임 1차 (21. 08. 28)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%8B%A4%ED%8A%B8%EA%B2%8C%EC%9E%84_1%EC%B0%A8.java

- 문자열에서 char값을 하나씩 가져오면서 switch 문으로 값 판단

 

------------------------------------------------------------------------------------------

 

같은 숫자는 싫어 (21. 08. 29)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EA%B0%99%EC%9D%80_%EC%88%AB%EC%9E%90%EB%8A%94_%EC%8B%AB%EC%96%B4.java

- 현재값과 이전값을 비교하여 다르면 List에 추가

- 완성된 List를 배열로 변환

 

------------------------------------------------------------------------------------------

 

나누어 떨어지는 숫자 배열 (21. 08. 29)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%82%98%EB%88%84%EC%96%B4_%EB%96%A8%EC%96%B4%EC%A7%80%EB%8A%94_%EC%88%AB%EC%9E%90_%EB%B0%B0%EC%97%B4.java

- divisor로 나누어지는 값을 리스트에 저장

- 리스트값을 하나씩 가져와 Collections.sort 메소드로 정렬 후 다시 배열로 반환

 

------------------------------------------------------------------------------------------

 

두 정수 사이의 합 (21. 08. 29)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%91%90_%EC%A0%95%EC%88%98_%EC%82%AC%EC%9D%B4%EC%9D%98_%ED%95%A9.java

- 전달받을 a, b에는 대소관계가 정해지지 않아 대소판단 후 사이값들의 총합을 구함

 

------------------------------------------------------------------------------------------

 

문자열 내 마음대로 정렬하기 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AC%B8%EC%9E%90%EC%97%B4_%EB%82%B4_%EB%A7%88%EC%9D%8C%EB%8C%80%EB%A1%9C_%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0.java

- 먼저 사전순으로 정렬한 후 특정 문자를 기준으로 정렬

- 사전순으로 먼저 정렬하면 특정 문자를 기준으로 정렬할 때 동일한 문자가 있어도 사전순으로 정렬됨

 

------------------------------------------------------------------------------------------

 

문자열 내 p와 y의 개수 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AC%B8%EC%9E%90%EC%97%B4_%EB%82%B4_p%EC%99%80_y%EC%9D%98_%EA%B0%9C%EC%88%98.java

- 문자열을 소문자로 변환 후 p, y 비교

 

------------------------------------------------------------------------------------------

 

문자열 내림차순으로 배치하기 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AC%B8%EC%9E%90%EC%97%B4_%EB%82%B4%EB%A6%BC%EC%B0%A8%EC%88%9C%EC%9C%BC%EB%A1%9C_%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0.java

- String을 char배열로 변환 후 StringBuilder를 이용해 문자열을 붙여넣어 반환

 

------------------------------------------------------------------------------------------

 

문자열 다루기 기본 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AC%B8%EC%9E%90%EC%97%B4_%EB%8B%A4%EB%A3%A8%EA%B8%B0_%EA%B8%B0%EB%B3%B8.java

- 정규표현식으로 문제풀이 진행

 

------------------------------------------------------------------------------------------

 

서울에서 김서방 찾기 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%84%9C%EC%9A%B8%EC%97%90%EC%84%9C_%EA%B9%80%EC%84%9C%EB%B0%A9_%EC%B0%BE%EA%B8%B0.java

- 배열을 하나씩 돌면서 Kim을 찾은 후 인덱스를 반환

 

------------------------------------------------------------------------------------------

 

소수 찾기 (21. 08. 30)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%86%8C%EC%88%98_%EC%B0%BE%EA%B8%B0.java

https://banjjak1.tistory.com/17

- "에라토스테네스의 체"를 이용하여 소수 판별

- 큰 수가 소수인지 판별하는 방법으로, 2의 배수부터 지우고(자기자신 제외) 다음 숫자 3의 배수를 지우며(자기자신 제외) 이미 지워진 숫자에 접근한 경우 다음 숫자로 넘어가도록 함

 

------------------------------------------------------------------------------------------

 

수박수박수박수박수박수 (21. 08. 31)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98.java

- 나머지 연산으로 판단 후 문자열 조합하여 리턴

 

------------------------------------------------------------------------------------------

 

문자열을 정수로 바꾸기 (21. 08. 31)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84_%EC%A0%95%EC%88%98%EB%A1%9C_%EB%B0%94%EA%BE%B8%EA%B8%B0.java

- Integer.parseInt 메소드로 숫자 리턴

- 웬만하면 java에서 제공하는 메소드보단 직접 구현해서 해보기

 

------------------------------------------------------------------------------------------

 

시저암호 (21. 08. 31)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%8B%9C%EC%A0%80_%EC%95%94%ED%98%B8.java

- String에서 문자를 하나씩 가져와 n만큼 이동한 값이 'z'보다 크면 문자+n 에서 'z'를 뺀다.

그럼 'a'에서 얼만큼 더 가야하는지에 대한 값이 나오므로 문자'a'에 앞서 구한 값을 더하고 -1을 해주면 n만큼 이동한 값이 나온다.

대문자 'Z'도 마찬가지로 가능하다.

 

------------------------------------------------------------------------------------------

 

약수의 합 (21. 09. 01)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%95%BD%EC%88%98%EC%9D%98_%ED%95%A9.java

https://banjjak1.tistory.com/18

- 약수는 전달받은 숫자/2 보다 클 수 없으므로 for문 조건에 n/2를 해주어야 함

- 위 생각을 못하고 단순하게 작성..

 

------------------------------------------------------------------------------------------

 

이상한 문자 만들기 (21. 09. 01)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9D%B4%EC%83%81%ED%95%9C_%EB%AC%B8%EC%9E%90_%EB%A7%8C%EB%93%A4%EA%B8%B0.java

- 짝수번째인 경우 대문자로 변환

- 홀수번째인 경우 소문자로 변환

- toLowerCase(), toUpperCase() 메소드 이용하지 않고 알파벳 범위 정해서 구현

 

------------------------------------------------------------------------------------------

 

자릿수 더하기 (21. 09. 01)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9E%90%EB%A6%BF%EC%88%98_%EB%8D%94%ED%95%98%EA%B8%B0.java

- 단순히 각 자리수를 더하는 것이기 때문에 나머지 연산과 나누기 연산을 이용해서 빠르게 풀 수 있었으나

생각하지 못해서 문자열로 변환 후 다시 숫자로 반환..

- 반성하자

 

------------------------------------------------------------------------------------------

 

자연수 뒤집어 배열로 만들기 (21. 09. 01)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9E%90%EC%97%B0%EC%88%98_%EB%92%A4%EC%A7%91%EC%96%B4_%EB%B0%B0%EC%97%B4%EB%A1%9C_%EB%A7%8C%EB%93%A4%EA%B8%B0.java

- answer의 배열 길이를 정해주고 반복문을 통해 나머지 연산과 나누기 연산을 이용해 배열에 저장

 

------------------------------------------------------------------------------------------

 

최대공약수와 최소공배수 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98%EC%99%80_%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98.java

- 소인수분해를 이용한 풀이와 유클리드 호제법을 이용한 풀이 둘 다 작성

 

------------------------------------------------------------------------------------------

 

콜라츠 추측 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%BD%9C%EB%9D%BC%EC%B8%A0_%EC%B6%94%EC%B8%A1.java

- 짝수면 /2, 홀수면 *3 후 + 1

 

------------------------------------------------------------------------------------------

 

평균 구하기 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%8F%89%EA%B7%A0_%EA%B5%AC%ED%95%98%EA%B8%B0.java

- 배열의 모든값을 더해서 평균을 반환

 

------------------------------------------------------------------------------------------

 

하샤드 수 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%95%98%EC%83%A4%EB%93%9C_%EC%88%98.java

- 나머지 연산을 통해 각 자리의 숫자를 더해주고 하샤드 수인지 계산

 

------------------------------------------------------------------------------------------

 

핸드폰 번호 가리기 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%95%B8%EB%93%9C%ED%8F%B0_%EB%B2%88%ED%98%B8_%EA%B0%80%EB%A6%AC%EA%B8%B0.java

- StringBuilder로 변환 후 끝 4자리를 제외하고 '*' 처리

 

------------------------------------------------------------------------------------------

 

행렬의 덧셈 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%ED%96%89%EB%A0%AC%EC%9D%98_%EB%8D%A7%EC%85%88.java

- 이중 for문으로 2차원 배열 arr1, arr2에 접근 후 더하여 answer에 저장

 

------------------------------------------------------------------------------------------

 

x만큼 간격이 있는 n개의 숫자 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/x%EB%A7%8C%ED%81%BC_%EA%B0%84%EA%B2%A9%EC%9D%B4_%EC%9E%88%EB%8A%94_n%EA%B0%9C%EC%9D%98_%EC%88%AB%EC%9E%90.java

- int + long 의 경우 결과값이 long으로 연산결과가 나온다.

int + int 의 경우 결과값이 long으로 연산결과가 나온다.

따라서 인자값을 int형에서 long으로 바꿔주면 해결 가능하다.

 

------------------------------------------------------------------------------------------

 

직사각형 별찍기 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95_%EB%B3%84%EC%B0%8D%EA%B8%B0.java

- 구구단과 비슷한 이중포문 반복문제

 

------------------------------------------------------------------------------------------

 

위클리챌린지 4주차 (21. 09. 02)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%9C%84%ED%81%B4%EB%A6%AC%EC%B1%8C%EB%A6%B0%EC%A7%80_4%EC%A3%BC%EC%B0%A8.java

- 직업을 class화 해서 풀이했으나 다른 풀이보다 성능 및 코드길이가 좋지않음..ㅠㅠ

 

------------------------------------------------------------------------------------------

 

정수 내림차순으로 배치하기 (21. 09. 03)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%A0%95%EC%88%98_%EB%82%B4%EB%A6%BC%EC%B0%A8%EC%88%9C%EC%9C%BC%EB%A1%9C_%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0.java

- 숫자를 문자열로 변환 후 split으로 잘라 각 숫자들을 내림차순으로 정렬하고 split으로 자른 배열을 숫자 형태로 변환

 

------------------------------------------------------------------------------------------

 

정수 제곱근 판별 (21. 09. 03)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%A0%95%EC%88%98_%EC%A0%9C%EA%B3%B1%EA%B7%BC_%ED%8C%90%EB%B3%84.java

- 전달받은 숫자를 Math.sqrt 메소드를 이용해 루트연산하고 1로 나눈 나머지가 0보다 크면 제곱근이 아니라 판단하여 -1 반환, 0이면 제곱근으로 판단하고 결과값 반환

 

------------------------------------------------------------------------------------------

 

짝수와 홀수 (21. 09. 03)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%A7%9D%EC%88%98%EC%99%80_%ED%99%80%EC%88%98.java

- 단순히 나머지 연산을 통해 짝수인지 홀수인지 판단하는 문제

 

------------------------------------------------------------------------------------------

 

제일 작은 수 제거하기 (21. 09. 05)

https://github.com/banjjak2/Programmers/blob/main/Level1/%EC%A0%9C%EC%9D%BC_%EC%9E%91%EC%9D%80_%EC%88%98_%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0.java

- 가장 작은 수를 구하고 answer 배열에 저장할 때 해당 작은 수를 제외하고 저장

 

------------------------------------------------------------------------------------------

 

최대공약수, 최소공배수 구하기


공약수 : 두 개 이상의 자연수(양의 정수) 중에서 공통된 약수

최대공약수 : 공약수 중 제일 큰 약수

서로소 : 공약수가 1뿐인 2개 이상의 자연수

 

최대공약수

 - 소인수분해로 구하기 (서로소가 나올 때까지 소수로 계속 나눔)

 - 출처 : https://mathbang.net/202

소인수분해

 - 최대공약수는 6x2 = 12

 

공배수 : 2개 이상의 자연수 중에서 공통된 배수

최소공배수 : 공배수 중 제일 작은 공배수

 

최소공배수

 - 위 사진에서 최소공배수는 6x2x5x4 = 240 이다.


소인수분해를 이용한 최대공약수, 최소공배수 구하기

// 소인수분해를 이용한 풀이
// 결과값 = 공약수들 + 서로소들
public static int[] factorization(int n, int m){
    int divisor = 2;
    List<Integer> facts = new ArrayList<Integer>();
    int[] retData;

    while(true){
        if ((n % divisor == 0) && (m % divisor == 0)){
            facts.add(divisor);
            n /= divisor;
            m /= divisor;
        }
        else{
            if (divisor > n || divisor > m){
                facts.add(n);
                facts.add(m);
                break;
            }

            divisor++;
        }
    }

    retData = new int[facts.size()];
    for(int i=0; i<facts.size(); i++){
        retData[i] = facts.get(i);
    }

    return retData;
}

 

유클리드 호제법을 이용한 최대공약수, 최소공배수 구하기

 - 2개의 자연수 a, b에 대해서 a를 b로 나눈 나머지를 r이라고하면 (단, a>b) a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이 성질에 따라 b를 r로 나눈 나머지 r0를 구하고 다시 r을 r0로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a, b의 최대 공약수이다.

 - 출처 : https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C_%ED%98%B8%EC%A0%9C%EB%B2%95

 

// gcd : 최대공약수
// lcm : 최소공배수
public static int[] gcdlcm(int n, int m){
    int gcd;
    int lcm;

    gcd = gcd(n, m);
    lcm = (n * m) / gcd;

    return new int[] { gcd, lcm };
}

public static int gcd(int n, int m){
    // 나머지가 0이면
    if (m == 0){
        // 나눈값 반환
        return n;
    }

    // 나눈 수, 나머지 값
    return gcd(m, n % m);
}

'0x20. 알고리즘' 카테고리의 다른 글

약수의 총 합 구하기  (0) 2021.09.01
소수 판별 (에라토스테네스의 체)  (0) 2021.08.30
두 점 사이의 거리 구하기  (1) 2021.07.13

약수의 총 합 구하기


프로그래머스의 약수의 총 합을 풀었는데 정석의 방법으로 풀었었다.

int answer = 0;

for(int i=1; i<=n; i++){
    if (n % i == 0){
        answer += i;
    }
}

return answer;

다른 풀이를 보니 아래와 같이 풀었는데, 그 이유는 간단했다.

int answer = 0;

for(int i=1; i<=n / 2; i++){
    if (n % i == 0){
        answer += i;
    }
}

answer += n;

return answer;

for문의 조건에서 n/2를 한 이유는 약수는 n의 절반이 넘는 값이 나올 수 없기 때문인데

예를들어, 12의 경우 약수는 1, 2, 3, 4, 6, 12이며 1x12 == 2x6 == 3x4 == 12 로 계산이 가능하다.

따라서 어떤 수가 들어오더라도 n의 약수 중 n의 절반이 넘는 값이 약수가 될 수 없다.

그래서 아래 풀이의 경우 연산횟수를 절반으로 줄일 수 있다.

에라토스테네스의 체


에라토스테네스의 체 (위키)

  - 어떤 수가 소수인지 판별할 수 있는 방법

  - 2의 배수부터 지우고(자기자신 제외) 다음 숫자로 넘어가 3의 배수를 지우고(자기자신 제외)를 반복

  - 지운 숫자에 접근할 경우 다음 숫자로 넘어감

 

public int eratosthenes(int n){
    int[] arr = new int[n - 1]; // 0, 1 제외하고 n은 포함되어야 하니까 -1
    int count = 0;

    for(int i=2; i<=n; i++){
        arr[i - 2] = i;
    }
    
    for(int i=2; i<=n; i++){
        if (arr[i - 2] == 0){
            continue;
        }

        for(int j=i+i; j<=n; j+=i){ // 자기자신 제외 (i + i), 배수만큼 (j + i)
            arr[j - 2] = 0;
        }
    }

    for (int i : arr) {
        if (i != 0){
            count++;
        }
    }

    return count;
}

'0x20. 알고리즘' 카테고리의 다른 글

[JAVA] 최대공약수, 최소공배수 구하기  (0) 2021.09.02
약수의 총 합 구하기  (0) 2021.09.01
두 점 사이의 거리 구하기  (1) 2021.07.13

맥북 프로 13인치 2015년도 기준이다.

 

좌측 상단 사과버튼 클릭 후 시스템 환경설정 -> 키보드 -> 입력소스 -> 두벌식 삭제 후 다시 설정

 

 

https://www.clien.net/service/board/cm_mac/15608025

 

빅서 설치 이후 한글 입력이 느리다면 : 클리앙

비단 빅서만의 문제는 아니고 매번 os 메이저 업데이트가 이루어지면 벌어지는 일인데요. 메이저 업데이트, 혹은 작은 판올림 이후 한글 입력시 자음과 모음이 분리되거나 입력하는 속도만큼 제

www.clien.net

 

'0x40. 기타' 카테고리의 다른 글

h2 database 설치 및 실행 방법  (0) 2021.09.15

+ Recent posts