알고리즘/백준

[백준 10816] 숫자카드2 - JAVA[이중 for문, 이분탐색, 자료구조 : 해시맵, Counting] 기법

놀이방사장님 2024. 1. 14. 01:15
728x90
반응형

안녕하세요 놀이방 사장입니다.

 

이번 포스팅은 백준 10816번

"숫자카드" 구현 포스팅입니다.

 

 

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,0

www.acmicpc.net

 

이번 포스팅은 글 제목에서 나오듯이 4가지 기법으로 풀어보겠습니다.

 

문제는 이해는 쉽습니다.

두 개의 배열이 주어지는데 두번째 배열에 해당하는 값이 첫번쨰 배열에 몇개 있는지 출력하면 되는 문제입니다.

 

1. 이중 for문 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;

public class Main{
    public static void main(String args[]) throws Exception {
        BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(System.out));
        int n = Integer.parseInt(br.readLine());
        String[] wordN = br.readLine().split(" ");
        int m = Integer.parseInt(br.readLine());
        String[] wordM = br.readLine().split(" ");

        for(int i=0; i< wordM.length; i++){
            int count = 0;
            for(int j=0; j<wordN.length; j++){
                if(wordM[i].equals(wordN[j])){
                    count++;
                }
            }
            System.out.print(count + " ");
        }
    }
}

두 개의 배열을 받고 이중 for으로 하나씩 비교해주면 하나의 값이 비교가 끝나면 count 변수를 출력해주는 방법입니다.

 

가장 쉬운 방법이라고 생각합니다.

 

2. 이분탐색

이분탐색을 구현하고 이분탐색으로 찾는 방법입니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main{
    public static int getLowCount(int[] arr, int x){
        int lower = 0;
        int high = arr.length;

        while(lower < high){
            int mid = (lower + high) / 2; //중간위치
            if(x <= arr[mid]){
                high = mid;
            }else{
                lower = mid+1;
            }
        }
        return lower;
    }

    public static int getHighCount(int[] arr, int x){
        int lower = 0;
        int high = arr.length;
        while(lower < high){
            int mid = (lower + high) / 2;
            if(arr[mid] > x){
                high = mid;
            }else{
                lower = mid+1;
            }
        }
        return lower;
    }
    public static void main(String args[]) throws Exception {
        BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] wordN = new int[n];
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        for(int i =0; i<n; i++){
            wordN[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(wordN);
        int m = Integer.parseInt(br.readLine());
        StringTokenizer stM = new StringTokenizer(br.readLine(), " ");
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<m; i++){
            int x = Integer.parseInt(stM.nextToken());
            sb.append(getHighCount(wordN, x) - getLowCount(wordN, x)).append(' ');

        }
        System.out.println(sb);
    }
}

 

 

3. 자료구조 : 해시맵을 사용하는 방법입니다.

해시맵으로 푼 방법은 해당하는 키값이 있으면 value를 하나씩 추가해주는 방법으로 풀었습니다.

이 방법으로 풀기 위해서는 getOrDefalut메소드를 사용하면 됩니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main{
    public static void main(String args[]) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        /*
        HashMap<key, value>
        key = 입력되는 원소
        value = 원소의 개수(=중복 입력된 원소의 수)
        */
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int wordN[] = new int[n];
        for(int i=0; i<n; i++){
            int key = Integer.parseInt(st.nextToken());
            map.put(key , map.getOrDefault(key,0)+1);
        }
        int m = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine(), " ");
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<m; i++){
            int key = Integer.parseInt(st.nextToken());
            sb.append(map.getOrDefault(key,0)).append(' ');
        }
        System.out.println(sb);
    }
}

 

 

4. Counting기법

이 방법은 N의 갯수의 *2로 배열을 선언해줍니다. 두배로 한 이유는 -1도 있기 때문에

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
    public static int[] countArr = new int[20000001];
    public static void main(String args[]) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        for(int i = 0; i<n; i++){
            int idx = Integer.parseInt(st.nextToken());
            countArr[idx+10000000]++;
        }

        int m = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        st = new StringTokenizer(br.readLine(), " ");
        for(int i=0; i<m; i++){
            int arrIdx = Integer.parseInt(st.nextToken());
            sb.append(countArr[arrIdx+10000000]).append(' ');
        }
        System.out.println(sb);
    }
}

코드에서 보이듯이 해당하는 값이 있으면을 추가해서 배열값을 ++ 해줍니다. a배열기준으로

10000000

 

그 후에 b배열 기준으로 위에 이미지에 해당하는 인덱스의 값을 출력해주면 원하는 답이 나옵니다.

 

 

이런 간단한 문제에도 여러 방법이 있으니 알아가시는 게 좋을 거 같습니다.

 

감사합니다.

반응형