자바 Integer 클래스 메서드 정리
Integer 클래스란? Java에서 정수와 관련된 유틸리티 메서드를 모아둔 클래스. int 타입의 데이터를 객체로 래핑하여 유용한 기능들을 제공함 String 클래스 메서드 종류 parseInt(String s): 문자열을 정수로 변환 String numStr = "123"; int num = Integer.parseInt(numStr); System.out.println(num); // 출력: 123 toString(int i): 정수를 문자열로 변환 int num = 123; String numStr = Integer.toString(num); System.out.println(numStr); // 출력: "123" int1.compareTo(int2): int1와 int2의 값을 비교 (int1 ..
2024.04.20
프로그래머스: 배열 만들기 2 (자바, Java)
[프로그래머스] 배열 만들기 2 문제 정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오 만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오 나의 답안 문제를 처음 보고 가장 먼저 생각한 구조는 아래와 같다. 1. l부터 r까지 숫자를 문자열로 형변환 2. 각 자리수가 5 혹은 0으로 이루어졌는지 체크 3. 해당 숫자만 리스트에 저장 4. 리스트를 배열로 변환하여 return 그러나 좀 더 괜찮은 방법이 없을까 아주 긴 시간 고민했다. (5로 나누고 10으로 나눴을 때 나머지가 0 또는 1이고 등등...) 그러다 생각해낸 것이 1. 숫자를 5로 나눴을 때..
2024.04.19
프로그래머스: 수 조작하기 2 (자바, Java)
[프로그래머스] 수 조작하기 2 문제 정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다. "w" : 수에 1을 더한다. "s" : 수에 1을 뺀다. "d" : 수에 10을 더한다. "a" : 수에 10을 뺀다. 그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog 이다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있다. 주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 메서드를 완성하라 나의 답안 StringBulider 선언 발생할 수 있는 경우의 수가 4가지 ..
2024.04.17
백준: 1339 단어 수학 (자바, Java)
[백준] 1339 단어 수학 (https://www.acmicpc.net/problem/1339) 문제 민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다. 단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다. 예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다. N개의 단어가 주어졌을 때, 그 수의 합을 최대로..
2024.04.15
프로그래머스 풀이: (자바, Java)
2024.04.13
프로그래머스: 이어 붙인 수 (자바, Java)
[프로그래머스] Level 0 이어 붙인 수 문제 정수가 담긴 리스트 num_list가 주어질 때 num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 메서드를 작성하라. 나의 답안 StringBulider를 이용, 리스트 내 원소들을 하나씩 조회하여 짝수와 홀수를 구별하고 각각을 StringBuilder에 추가 최종적으로 odd, even 변수를 String으로 전환 후 int로 변환하여 두 값을 더함 class Solution { public int solution(int[] num_list) { StringBuilder odd = new StringBuilder(); StringBuilder even = new StringBuild..
2024.04.12
자바 재귀메서드, 재귀함수 (사용법, 예시, 개념)
자바 프로그래머스에서 열심히 코딩 공부를 하던 중, 재귀함수가 사용된 것을 처음 보았다. 재귀함수는 자기 함수에서 자기 자신을 호출하는 함수를 말하는 것으로, 반복적인 연산 처리에 특히 유용하게 사용되는 재귀함수에 대해 알아보았다. 재귀메서드, 재귀함수 개념 재귀메서드, 재귀함수는 함수가 자기 자신을 호출하는 것을 말함. 일반적 구조 public int 메서드명(입력값) { if (종료조건) { // 종료 조건 만족하면 종료 return 기본값; } return 재귀함수(조정된 입력값); // 자기자신 호출 } 재귀함수는 함수 내에서 자신을 호출하고, 호출할 때마다 입력값을 조정하여 종료조건을 만족할 때까지 자신을 호출하도록 설계된다. 재귀함수 동작 원리 재귀 함수는 스택 자료구조를 통해 동작함 각각의 ..
2024.04.11
프로그래머스 풀이: 주사위게임 2(자바, Java)
[프로그래머스] Level 0 주사위게임2 문제 세 주사위를 던졌을 때 나온 숫자를 각각 a, b, c라고 할 때 얻는 점수는 다음과 같다. 세 숫자가 모두 다르면 a + b + c 점을 얻는다. 두 숫자는 같고 나머지 숫자는 다르다면 (a + b + c) × (a2 + b2 + c2 )점을 얻 는다. 세 숫자가 모두 같다면 (a + b + c) × (a2 + b2 + c2 ) × (a3 + b3 + c3 )점을 얻 는다. 세 정수 a, b, c가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 메서드를 작성하라. 나의 답안 주사위 4개인 문제의 경우처럼 배열을 활용하여 오름차순 정렬 후 if문을 작성했는데, 다른 답안들을 보니 굳이 배열을 사용할 필요 없이 훨씬 효율적이고 간결한 ..
2024.04.10
프로그래머스 풀이: 코드 처리하기 (자바, Java)
[프로그래머스] Level 0 코드 처리하기 문제 문자열 code가 주어집니다. code를 앞에서부터 읽으면서 만약 문자가 "1"이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다. mode는 0과 1이 있으며, i를 0부터 code의 길이 - 1까지 1씩 키워나가면서 code[i] 값에 따라 다음과 같이 행동합니다. mode = 0일 때 code[i]가 "1"이 아니면 i가 짝수일 때만 ret의 맨 뒤에 code[i]를 추가합니다. code[i]가 "1"이면 mode를 0에서 1로 바꿉니다. mode = 1일 때 code[i]가 "1"이 아니면 i가 홀수일 때만 ret의 맨 뒤에 code[i]를 추가합니다. code[i]가 "1"이면 mode를 1에서 0으로 바..
2024.04.09
프로그래머스 풀이: 완주하지 못한 선수 (자바, Java)
[프로그래머스] Level 1 완주하지 못한 선수 문제 마라톤 경주에서 참가자들 중 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤 참가 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요. 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다. completion의 길이는 participant의 길이보다 1 작습니다. 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다. 참가자 중에는 동명이인이 있을 수 있습니다. 나의 답안(효율성 테스트 탈락) 리스트로 변환한 후, 완주한 참가자의 이름..
2024.04.08

자바 Integer 클래스 메서드 정리

친환경 개발자
|2024. 4. 20. 22:10

Integer 클래스란?

Java에서 정수와 관련된 유틸리티 메서드를 모아둔 클래스.

int 타입의 데이터를 객체로 래핑하여 유용한 기능들을 제공함

 

 

 

 

String 클래스 메서드 종류

  1. parseInt(String s): 문자열을 정수로 변환

    String numStr = "123";
    int num = Integer.parseInt(numStr);
    System.out.println(num); // 출력: 123


  2. toString(int i): 정수를 문자열로 변환

    int num = 123;
    String numStr = Integer.toString(num);
    System.out.println(numStr); // 출력: "123"


  3. int1.compareTo(int2): int1와 int2의 값을 비교 (int1 > int2: 1 / int1 < int2: -1 / int == int2: 0)

    Integer num1 = 100;
    Integer num2 = 200;
    int result = num1.compareTo(num2);
    System.out.println(result); // 출력: -1


  4. intValue(): Integer 객체의 값을 int형으로 반환

    Integer num = 123;
    int intValue = num.intValue();
    System.out.println(intValue); // 출력: 123


  5. valueOf(int i): 주어진 int 값을 Integer 객체로 변환하여 반환

    int num = 123;
    Integer integerObj = Integer.valueOf(num);
    System.out.println(integerObj); // 출력: 123

  6. toBinaryString(int n): 정수를 2진수 문자열로 변환

     
  7. bitCount(int n): 정수의 2진수 표현에서 1의 개수 반환

    int num = 10; // 이진수: 1010 (2진수로 1의 개수)
    int count = Integer.bitCount(num);
    System.out.println(count); // 출력: 2


  8. reverse(int i): 정수의 비트를 역순으로 뒤집은 값 반환

    int num = 12345;
    int reversedNum = Integer.reverse(num);
    System.out.println(reversedNum); // 출력: 1260388352

 

 

 

 

 

관련 문제

 

[프로그래머스 문제]

정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오

 

 

 

 

<모범 답안>

import java.util.ArrayList;

class Solution {
    public int[] solution(int l, int r) {

        ArrayList<Integer> list = new ArrayList<>();

        for (int i = 1; i < 64; i++) {
            int num = Integer.parseInt(Integer.toBinaryString(i)) * 5;
            if (l <= num && num <= r)
                list.add(num);
        }

        return list.isEmpty() ? new int[] { -1 } : list.stream().mapToInt(i -> i).toArray();
    }
}

 

[프로그래머스] 배열 만들기 2

 

 

 

문제

정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오

 

 

 

나의 답안

문제를 처음 보고 가장 먼저 생각한 구조는 아래와 같다.

 

1. l부터 r까지 숫자를 문자열로 형변환

2. 각 자리수가 5 혹은 0으로 이루어졌는지 체크

3. 해당 숫자만 리스트에 저장

4. 리스트를 배열로 변환하여 return

 

 

 

그러나 좀 더 괜찮은 방법이 없을까 아주 긴 시간 고민했다.

(5로 나누고 10으로 나눴을 때 나머지가 0 또는 1이고 등등...)

 

그러다 생각해낸 것이

 

1. 숫자를 5로 나눴을 때, 1 혹은 0으로 이루어진다.

2. [5, 50, 55, 500, 505, 550 .... ] 각 숫자를 5로 나누면 

    [1, 10, 11, 100, 101, 110 ...] 이고, 이진수로 생각하면 [1, 2, 3, 4, 5...] 와 같네?

3. l, r 까지 숫자 범위 내까지 이진수를 십진수로 바꿔 5를 곱한 값들을 배열에 넣으면 완성

 

 

그러나, 이것을 코드로 구현하는 것은 내 코딩 지식으로 도저히 이루어지지 않아.

결국 며칠을 고민하다 원래 생각했던 구조대로 작성하였다..

 

<완전 오답입니다>
static int[] solution(int l, int r) {
        ArrayList<Integer> arr = new ArrayList<>();

        for (int i=l; i<=r; i++) {
            if (i % 5 == 0) {
                int n = i / 5;
                if (n % 10 == 0 || n % 10 == 1) {
                    arr.add(i);
                }
            }
        }

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

        return result;
    }

 

 

모범 답안

import java.util.ArrayList;

class Solution {
    public int[] solution(int l, int r) {

        ArrayList<Integer> list = new ArrayList<>();

        for (int i = 1; i < 64; i++) {
            int num = Integer.parseInt(Integer.toBinaryString(i)) * 5;
            if (l <= num && num <= r)
                list.add(num);
        }

        return list.isEmpty() ? new int[] { -1 } : list.stream().mapToInt(i -> i).toArray();
    }
}

 

  • 1 <= l <=  r <= 1,000,000 조건이 있으므로, 1부터 64까지 숫자를 이진수로 변환 (1 ~ 1000000)
  • 변환한 이진수 문자열을 정수로 변환한 후 5를 곱하여 num 변수에 저장
  • 해당 숫자(num)가 l, r 사이의 값인 경우에만 리스트에 추가

 

 

내가 몇시간씩 고민했지만 결국 실패한 코드가 이렇게 간단히 적히다니...

아직 너무 부족함을 느낀다. 열심히 공부해야겠다.

 

 

 

 

복습

       Integer 클래스 메서드

  • Integer.parseInt(String s) :문자열을 int형으로 변환
  • Integer.parseInt(String s, int radix) : 다른 진수의 값 → 10진수로 변환
  • Integer.toBinaryString(int i) : 정수를 이진수로 변환

[프로그래머스] 수 조작하기 2

 

 

 

문제

정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다.

  • "w" : 수에 1을 더한다.
  • "s" : 수에 1을 뺀다.
  • "d" : 수에 10을 더한다.
  • "a" : 수에 10을 뺀다.

그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog 이다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있다.

주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 메서드를 완성하라

 

 

 

 

나의 답안

 

  1. StringBulider 선언

  2. 발생할 수 있는 경우의 수가 4가지 (1, -1, 10, -10) 이므로 switch 문을 사용
  3. numLog[i]의 값은 numLog[i-1] 값을 w, a, s, d에 따라 조정한 숫자이므로,
    numLog[i] - numLog[i-1] 값을 통해 w, a, s, d 여부를 판단하여
    sb에 순서대로 저장했다.

 

 

class Solution {
    public String solution(int[] numLog) {
        StringBuilder sb = new StringBuilder();
        
        for (int i=1; i<numLog.length; i++) {
            switch (numLog[i] - numLog[i-1]) {
                case 1: sb.append("w");
                    break;
                case -1: sb.append("s");
                    break;
                case 10: sb.append("d");
                    break;
                case -10: sb.append("a");
                    break;
                default: break;
            }
        }
            
            return sb.toString();
    }
}

 

 

 

 

모범 답안

class Solution {
    public String solution(int[] numLog) {
        String answer = "";
        for(int i=1; i<numLog.length; i++){
            int j = numLog[i-1] - numLog[i];
            switch(j){
                case -1 : answer+='w'; break;
                case 1 : answer+='s'; break;
                case -10 : answer+='d'; break;
                case 10 : answer+='a'; break;
            }
        }
        return answer;
    }
}

 

  • StringBuilder 대신 String을 선언하여 문자를 추가했다.
  • String을 통해 값을 추가할 경우, 추가할 때마다 프로그램 내부적으로 매번 변수 선언을 반복하여
    비효율적일 수 있어 StringBuilder 사용함.  (책에서 봤음)
  • switch문 마지막에 default는 생략해도 무방하다는 것을 깨달았다.

 

복습

       switch문 구조

  • switch (입력 변수) {
        case 입력값 1: 수행할 문장 1;
            break;
        case 입력값 2: 수행할 문장 2;
            break;


        ....


        default: 수행할 문장 n;
            break;
    }

  • 입력 변수의 값이 각 case의 입력값과 같을 경우 해당 case의 수행할 문장을 수행한다.

백준: 1339 단어 수학 (자바, Java)

친환경 개발자
|2024. 4. 15. 21:48

[백준] 1339 단어 수학  (https://www.acmicpc.net/problem/1339)

 

 

 

문제

민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.

단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.

예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다.

N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.

 

 

 

 

나의 답안

우선 입력받은 단어들을 하나씩 String[] (크기 N) 배열에 담고,

 

for문을 이용해 하나씩 불러와 단어의 글자수가 가장 긴 것을 찾고

 

가장 긴 단어의 맨 앞글자에 9를 넣는 방식을 생각해보았으나,

 

 

 

글자 수 가장 큰 단어를 찾은 후 긴 순서대로 재정렬하고,

 

앞글자부터 9, 8 ,7 을 집어넣을 경우

 

반복문이 너무 복잡해져 작성해보다가 실패했다.

 

 

 

이후 한참을 생각해봐도 코드 구성이 생각나지 않아 다른 분들의 훌륭한 답안들을 참고했다...

 

 

모범 답안

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        //n값 및 단어 입력받기 
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String [] arr = new String[n];
        int [] alpha = new int[26];
        for(int i=0; i<n; i++){
            arr[i] = sc.next();
        }

        //알파벳 빈도수 및 글자수에 따른 가중치 부여
        for(int i=0; i<n; i++){
            int temp = (int)Math.pow(10,arr[i].length()-1);
            for(int j=0; j<arr[i].length(); j++){
                alpha[(int)arr[i].charAt(j)-65]+=temp;
                temp /=10;
            }
        }

        //정렬 및 단어 빈도수 별 가중 결과값 합산
        Arrays.sort(alpha);
        int index = 9;
        int sum =0;
        for(int i=alpha.length-1; i>=0; i--){
            if(alpha[i] == 0){
                break;
            }
            sum+= alpha[i]*index;
            index--;
        }
        System.out.println(sum);
    }
}

 

  1. n값 및 단어 입력 받기
    - Scanner를 사용하여 단어의 수(n)와 단어의 문자열을 입력 받고, arr 배열에 넣음
    - 각 단어에서 포함된 알파벳들의 빈도를 체크하기 위한 alpha배열 선언 (26은 알파벳 개수!)

  2. 알파벳 빈도수 및 글자수에 따른 가중치 부여
    - 각 문자열의 가중치를 계산하여 알파벳 빈도수 배열 alpha에 누적
    - 각 문자열을 순회하면서 문자에 따른 가중치를 계산하고, alpha 배열의 해당 인덱스에 가중치를 더함
       예) ABCD > A가 포함된 위치(alpha[0])에 10의 3승, 즉 1000을 더함. B:100, C:10, D:1 더해짐

  3. 정렬 및 단어 빈도수 별 가중 결과값 합산
    - alpha 배열을 내림차순으로 정렬 : 가장 빈도와 가중치가 낮은 알파벳부터 순서대로 정렬
    - 가장 큰 수부터 9부터 0까지의 숫자를 곱하여 최종 결과값(총합)을 계산

 

 

 

알파벳 배열을 별도로 선언하여자리수가 높은 수에 10의 지수를 이용하여 가중치를 주고, 여러번 나온 알파벳에 경우에는 그에 맞는 가중 점수를 부여하여 최대값을 구한다는 점이 매우 인상깊었다.

 

 

 

프로그래머스 풀이: (자바, Java)

친환경 개발자
|2024. 4. 13. 23:51

[프로그래머스] Level 0 이어 붙인 수

 

 

 

문제

정수가 담긴 리스트 num_list가 주어질 때

 

num_list의 홀수만 순서대로 이어 붙인 수와

 

짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 메서드를 작성하라.

 

 

 

 

나의 답안

 

StringBulider를 이용,

 

리스트 내 원소들을 하나씩 조회하여

짝수와 홀수를 구별하고 각각을 StringBuilder에 추가

 

최종적으로 odd, even 변수를 String으로 전환 후 int로 변환하여

두 값을 더함

class Solution {
    public int solution(int[] num_list) {
        StringBuilder odd = new StringBuilder();
        StringBuilder even = new StringBuilder();
        
        for(int i=0; i<num_list.length; i++) {
            if (num_list[i]%2 == 1) {
                even.append(num_list[i]);
            } else {
                odd.append(num_list[i]);
            }
        }
        
        return Integer.parseInt(odd.toString()) + Integer.parseInt(even.toString());
    }
}

 

다른 답안들을 보니

 

내 답안은 StringBuilder를 선언하고

 

불필요하게 String 및 int형으로 변환하하는 과정을 거쳐 코드가 복잡해졌다.

 

 

모범 답안

class Solution {
    public int solution(int[] num_list) {
        int even = 0;
        int odd = 0;

        for (int num : num_list) {
            if (num % 2 == 0) {
                even = even * 10 + num;
            } else {
                odd = odd * 10 + num;
            }
        }

        return odd + even;
    }
}
  • 기존 odd, even 값에서 10을 곱한 후 새로운 수를 더해줌으로써
    불필요한 형변환을 방지했다는 점이 좋은 아이디어였다.

 

 

자바 프로그래머스에서 열심히 코딩 공부를 하던 중,

 

재귀함수가 사용된 것을 처음 보았다.

 

재귀함수는 자기 함수에서 자기 자신을 호출하는 함수를 말하는 것으로,

 

반복적인 연산 처리에 특히 유용하게 사용되는

 

재귀함수에 대해 알아보았다.

 

 

 

 

 

 

 

 

 

재귀메서드, 재귀함수 개념

재귀메서드, 재귀함수는 함수가 자기 자신을 호출하는 것을 말함.

 

  • 일반적 구조
public int 메서드명(입력값) {

    if (종료조건) {              // 종료 조건 만족하면 종료
        return 기본값;
    }

    return 재귀함수(조정된 입력값);       // 자기자신 호출
}

 

재귀함수는 함수 내에서 자신을 호출하고,

 

호출할 때마다 입력값을 조정하여

 

종료조건을 만족할 때까지 자신을 호출하도록 설계된다.

 

 

 

 

 

재귀함수 동작 원리

재귀 함수는 스택 자료구조를 통해 동작함

 

각각의 재귀 호출은 스택 프레임에 쌓이고,

 

함수가 종료되면 해당 스택 프레임 제거

 

최종적으로 최하위 호출부터 차례대로 결과를 반환한다.

 

 

재귀함수 예시

<팩토리얼 구하는 메서드 작성>

public int factorial(int n) {
    if (n == 0 || n == 1) {       // 종료 조건
        return 1;
    }
    
    return n * factorial(n - 1);     // 자기 자신 호출
}

 

<제곱  구하는 메서드 작성>

    private int pow(int base, int exponent) {       // 종료 조건
        if(exponen == 0) return 1;

        return base * pow(base, exponent - 1);     // 자기 자신 호출
    }

 

 

 

 

 

재귀함수 장단점

장점

  • 간단하고 간결한 코드 작성 가능
  • 반복적인 문제를 효율적으로 해결할 수 있음
  • 문제를 하위 문제로 분할하여 해결할 수 있음

 


단점

  • 재귀 호출 시 스택 메모리를 사용하므로 메모리 부하 발생 가능
  • 종료 조건을 설정하지 않으면 무한 반복에 빠질 수 있음
  • 반복문보다 함수 호출에 추가적인 오버헤드가 발생할 수 있음

[프로그래머스] Level 0 주사위게임2

 

 

 

문제

세 주사위를 던졌을 때 나온 숫자를 각각 a, b, c라고 할 때 얻는 점수는 다음과 같다.

 

  • 세 숫자가 모두 다르면 a + b + c 점을 얻는다.
  • 두 숫자는 같고 나머지 숫자는 다르다면 (a + b + c) × (a2 + b2 + c2 )점을 얻 는다.
  • 세 숫자가 모두 같다면 (a + b + c) × (a2 + b2 + c2 ) × (a3 + b3 + c3 )점을 얻 는다.

세 정수 a, b, c가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 메서드를 작성하라.

 

 

 

 

나의 답안

 

주사위 4개인 문제의 경우처럼

 

배열을 활용하여 오름차순 정렬 후 if문을 작성했는데,

 

다른 답안들을 보니 굳이 배열을 사용할 필요 없이

 

훨씬 효율적이고 간결한 코드가 많이 존재했다..

 

import java.util.Arrays;

class Solution {
    public int solution(int a, int b, int c) {
        int[] dice = {a, b, c};
        Arrays.sort(dice);

        if (dice[0] != dice[1] && dice[1] != dice[2]) {
            return dice[0]+dice[1]+dice[2];
        } else if (dice[0] != dice[2]) {
            return (dice[0] + dice[1] + dice[2]) * (dice[0]*dice[0] + dice[1]*dice[1] + dice[2]*dice[2]);
        } else {
            return (dice[0] + dice[1] + dice[2]) * (dice[0]*dice[0] + dice[1]*dice[1] + dice[2]*dice[2]) * (dice[0]*dice[0]*dic
e[0] + dice[1]*dice[1]*dice[1] + dice[2]*dice[2]*dice[2]);
        }
    }
}

 

 

 

 

모범 답안

class Solution {
    public int solution(int a, int b, int c) {
        int answer = 1;

        int count = 1;
        if(a == b || a == c || b == c) {
            count++;
        }

        if(a == b && b == c) {
            count++;
        }

        for(int i = 1; i <= count; i++) {
            answer *= (pow(a,i)+pow(b,i)+pow(c,i));
        }

        return answer;
    }

    private int pow(int a, int b) {
        if(b == 0) return 1;
        return a * pow(a, b-1);
    }
}
  • count변수를 생성하여, 단계별로 제곱 수를 결정하도록 함
  • pow메서드를 재귀함수로 별도로 선언하여 간결성 및 효율성 제고

 

상황에 따라 제곱과 세제곱이 사용된다는 점을 이용하여

정말 영리하게 작성된 코드라는 생각이 든다.

나는 언제쯤 저렇게 생각할 수 있을까..

 

 

복습

      재귀함수

  • 자신의 함수 내에서 자기 자신을 호출하는 함수
  • 반복적 연산 시 효율성을 위해 주로 사용
// 팩토리얼 구하는 메서드 작성

public int factorial(int n) {

    if (n == 0 || n == 1) {       // 종료 조건(Base Case)
        return 1;
    }
    
    return n * factorial(n - 1);     // 자기 자신 호출(Recursive Call)
}

 

[프로그래머스] Level 0 코드 처리하기

 

 

 

문제

문자열 code가 주어집니다. code를 앞에서부터 읽으면서 만약 문자가 "1"이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다. mode는 0과 1이 있으며, i를 0부터 code의 길이 - 1까지 1씩 키워나가면서 code[i] 값에 따라 다음과 같이 행동합니다.

 

  • mode = 0일 때
    code[i]가 "1"이 아니면 i가 짝수일 때만 ret의 맨 뒤에 code[i]를 추가합니다.
    code[i]가 "1"이면 mode를 0에서 1로 바꿉니다.
  • mode = 1일 때
    code[i]가 "1"이 아니면 i가 홀수일 때만 ret의 맨 뒤에 code[i]를 추가합니다.
    code[i]가 "1"이면 mode를 1에서 0으로 바꿉니다.


문자열 code를 통해 만들어진 문자열 ret를 return 하는 solution 함수를 완성해 주세요.
단, 시작할 때 mode는 0이며, return 하려는 ret가 만약 빈 문자열이라면 대신 "EMPTY"를 return 합니다.

 

 

 

 

나의 답안

 

조건에 맞게 mode가 1일 때와 0일 때, code[i]가 1일 때 등 if 조건문을 달아 작성하였으며,

StringBulider 변수를 선언하여 문자를 추가하도록 하였다.

 

 

class Solution {
    public String solution(String code) {
        StringBuilder temp = new StringBuilder();
        int mode = 0;

        for (int i=0; i<code.length(); i++) {
            if (mode == 0) {
                if (code.charAt(i) == '1') {
                    mode += 1;
                } else if (code.charAt(i) != '1') {
                    if (i%2 == 0) {
                        temp.append(code.charAt(i));
                    }
                }
            } else if (mode == 1) {
                if (code.charAt(i) == '1') {
                    mode -= 1;
                } else if (code.charAt(i) != '1') {
                    if (i%2 != 0) {
                        temp.append(code.charAt(i));
                    }
                }
            }
        }
        String ret = temp.toString();
        return ret.isEmpty() ? "EMPTY" : ret;
    }
}

 

 

 

 

 

모범 답안

class Solution {
    public String solution(String code) {
        StringBuilder answer = new StringBuilder();
        int mode = 0;
        for (int i = 0; i < code.length(); i++) {
            char current = code.charAt(i);
            if (current == '1') {
                mode = mode == 0 ? 1 : 0;
                continue;
            }

            if (i % 2 == mode) {
                answer.append(current);
            }
        }
        return answer.length() == 0 ? "EMPTY" : answer.toString();
    }
}
  • 홀수와 짝수 구분을 mode를 이용해 작성함으로써 중첩 if문 사용 방지
  • 문자가 '1'일 때, mode 전환 또한 삼항연산자를 사용하여 한번에 작성
  • 마지막 return 시 새로운 변수 선언 없이 바로 toString을 통해 StringBulider 변수를 리턴 

 

 

중첩 if문을 사용하지 않음으로써 훨씬 코드가 간결하고 가독성이 좋아졌다.

더 가독성을 높이고 효율성을 높일 수 있는 코딩이 있을지 항상 생각하며 코딩하면 좋을 듯하다.

 

 

복습

      문자열(String)

  • String.charAt(인덱스) : 해당 인덱스에 위치한 문자값을 리턴
  • String.isEmpty(): 해당 문자열이 비어있는지 확인

 

      StringBuilder

  • sb.append(문자열): 해당 문자열을 새로 추
  • sb.insert(인덱스, 문자열): 해당 위치에 문자열을 삽입 (해당 위치의 문자열을 뒤로 밀어 삽입)
  • sb.toString(): 문자열 자료형으로 변환

[프로그래머스] Level 1 완주하지 못한 선수

 

 

 

문제

마라톤 경주에서 참가자들 중 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤 참가 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 

 

완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

 

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

 

 

 

 

 

나의 답안(효율성 테스트 탈락)

 

리스트로 변환한 후, 완주한 참가자의 이름을 하나씩 대조하여 제거한 후

 

최종적으로 리스트에 남은 1명의 참가자의 이름을 return하도록 작성하였으나,

 

효율성 테스트에서 시간 초과로 오답 처리되었다.

 

 

import java.util.ArrayList;
import java.util.Arrays;

class Solution {
    public String solution(String[] participant, String[] completion) {
        ArrayList<String> part = new ArrayList<>(Arrays.asList(participant));

        for (int i=0; i<completion.length; i++) {
            part.remove(completion[i]);
        }

        return part.get(0);
    }

 

 

 

 

 

다른 유저의 답안

import java.util.HashMap;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> hm = new HashMap<>();
        for (String player : participant) hm.put(player, hm.getOrDefault(player, 0) + 1);
        for (String player : completion) hm.put(player, hm.get(player) - 1);

        for (String key : hm.keySet()) {
            if (hm.get(key) != 0){
                answer = key;
            }
        }
        return answer;
    }
}

 

  • HashMap을 생성, 참가자 value값 +1, 완주자 value값 -1
  • getOrDefault 메서드를 사용하여 동명이인 있을 경우 오류에도 대비
    (HashMap에서는 같은 key값이 선언될 경우 value값이 변경되어 등록됨)

 

 

 

getOrDefault를 사용하는 부분에서 감탄했다.

이런 메서드들을 적재적소에 잘 활용할 수 있는 개발자가 되어야지..

 

 

복습

       리스트(List)

  • a.add(요솟값) : 해당 리스트에 원하는 요솟값을 추가
  • a.remove(인덱스): 해당위치 항목 삭제, 그 요솟값 리턴
  • a.remove(요솟값): 해당 요솟값을 삭제, true/false리턴
  • a.get(인덱스): 해당위치 요솟값 리턴

 

      맵(Map)

  • a.put(key값, value값): key와 value 추가
  • a.get(key값): key에 해당하는 value값 반환
  • a.getOrDefault(key값,얻을값): key에 해당하는 value값이 없을 때, null대신 얻을값을 반환
  • a.keySet(): 모든 key값을 모아 집합 자료형으로 리턴