• 분류 전체보기 (512)
    • 개발남노씨(Coding Test) (6)
    • 고농축 백엔드 (17)
    • 재귀함수 DFS 총정리 (1)
    • 프론트엔드 날개달기:Vuejs.React (1)
    • 훈훈한 javascript (5)
    • 렛츠기릿 자바스크립트 (18)
    • 나도코딩 (1)
      • 웹 스크래핑 (1)
    • 프로그래머스(자바스크립트) (41)
      • LV.0(자바스크립트) (41)
    • 프로그래머스(자바) (121)
      • LV.0(자바) (56)
      • LV.1(자바) (41)
      • LV.2(자바) (23)
    • 프로그래머스(파이썬) (127)
      • LV.0(파이썬) (46)
      • LV.1(파이썬) (51)
      • LV.2(파이썬) (30)
    • 임시저장소 (31)
    • 프로젝트 (0)
    • 자바 알고리즘 (13)
      • 알고리즘 직빵 자바 문법 (10)
      • String(문자열) (3)
    • 파이썬 알고리즘 (93)
      • 알고리즘 직빵 파이썬 문법 (20)
      • 알고리즘 백준 (2)
      • 파이썬 알고리즘(사고력기르기) (6)
      • 파이썬 탐색 & 시물레이션 (8)
      • 이분탐색 & 그리디 알고리즘 (10)
      • 스택, 큐, 해쉬, 힙 (10)
      • 완전탐색과 DFS기초 (12)
      • DFS, BFS 활용 (19)
      • 동적계획법 (6)
    • 자바 (27)
      • Java TPC(생각하고, 표현하고, 코딩하고) (17)
      • Java (중요하고, 이해 안 되고, 어려운) (10)
    • 스프링 (5)
      • 스프링 MVC 패턴 2편 (5)
hELLO · Designed By 정상우.
@@#@@

기록용 블로그

프로그래머스(자바)/LV.2(자바)

1차 캐시→ 익명 클래스★★, this참조변수, super() 생성자

2022. 12. 26. 13:43

익명클래스가 있는 경우-시간초과로 인한 실패

import java.util.*;
public class Solution {
    public static int solution(int cacheSize, String[] cities) {
        // city가 cache에 없는 경우에는 전부다 cache miss이다.
        if (cacheSize == 0) {
            return cities.length * 5;
        }

        // cities의 요소를 저장하기 위한 cache공간으로 LinkedHashMap을 사용한다.(익명객체)
        Map<String, String> cache = new LinkedHashMap<String, String>(cacheSize, 0.75f, true) {
            protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
                return this.size() > cacheSize;
            }
        };

        // 최초실행시간을 0으로 초기화한다.
        int executionTime = 0;

        // 대소문자를 구분하지 않으므로 전부다 대문자로 바꾸어 놓는다.
        for (String city : cities) {
            city = city.toUpperCase();

            // 만약에 city가 cache안에 있다면 cache hit이다.
            if (cache.containsKey(city)) {
                executionTime += 1;
            }
            // city가 cache안에 없는 경우: 애당초 없었던 경우, 꽉차서 없었던 경우
            else {
                executionTime += 5;
                // city는 key이고 null은 value이다.
                cache.put(city, "None");
            }
        }

        return executionTime;
    }
}

 

 

 

 

익명클래스를 별도로 분리한 경우-시간 초과로 실패 

import java.util.*;
public class Solution {
    public static int solution(int cacheSize, String[] cities) {
        // city가 cache에 없는 경우에는 전부다 cache miss이다.
        if (cacheSize == 0) {
            return cities.length * 5;
        }

        // cities의 요소를 저장하기 위한 cache공간으로 LinkedHashMap을 사용한다.
        Map<String, String> cache = new MyLinkedHashMap(cacheSize);

        // 최초실행시간을 0으로 초기화한다.
        int executionTime = 0;

        // 대소문자를 구분하지 않으므로 전부다 대문자로 바꾸어 놓는다.
        for (String city : cities) {
            city = city.toUpperCase();

            // 만약에 city가 cache안에 있다면 cache hit이다.
            if (cache.containsKey(city)) {
                executionTime += 1;
            }
            // city가 cache안에 없는 경우: 애당초 없었던 경우, 꽉차서 없었던 경우
            else {
                executionTime += 5;
                // city는 key이고 null은 value이다.
                cache.put(city, "None");
            }
        }

        return executionTime;
    }
}

class MyLinkedHashMap extends LinkedHashMap<String, String> {
    private int cacheSize;

    public MyLinkedHashMap(int cacheSize) {
        super(cacheSize, 0.75f, true);
        this.cacheSize = cacheSize;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
        return this.size() > cacheSize;
    }
}

 

 

 

MyLinkedHashMap의 조상인 LinkedHashMap에 있는 생성자의 형태 

public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}

 

 

 

LinkedHashMap조상인 HashMap에 있는 생성자의 형태 

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}

 

해설 

▶MyLinkedHashMap 클래스는 LinkedHashMap을 상속받고 있고, LinkedHashMap의 생성자를 호출하고 있습니다. 

 

즉, MyLinkedHashMap 클래스의 생성자에서는 super(cacheSize, 0.75f)로 LinkedHashMap 생성자를 호출하고 있습니다.

▶LinkedHashMap 생성자는 인자로 전달받은 initialCapacity와 loadFactor를 이용해 HashMap의 생성자를 호출합니다. 

그러면 HashMap의 생성자는 LinkedHashMap으로부터 받은 인자인 initialCapacity와 loadFactor를 이용해

HashMap 객체를 생성하고, LinkedHashMap은 이를 상속받습니다.

▶MyLinkedHashMap 클래스에서는 LinkedHashMap의 removeEldestEntry 메소드를 재정의하고 있습니다. 

   이 메소드는 LinkedHashMap에 새로운 값이 추가될 때(cache.put)마다 호출되는 메소드로,

   이 메소드가 true를 반환하면 LinkedHashMap에서 가장 오래된 값을 삭제합니다.

▶ MyLinkedHashMap 클래스에서는 removeEldestEntry 메소드에서

    MyLinkedHashMap size()가 cacheSize보다 크면 true를, 그렇지 않으면 false를 반환하게 구현하고 있습니다.

 

 

▶ 따라서 removeEldestEntry 메소드에서 size() > cacheSize를 반환하면, 맵의 크기(size)가 cacheSize보다 크면

    가장 오랫동안 사용되지 않은 요소를 제거하라고 LinkedHashMap에 알려줍니다. 

 

 

 

오답임

import java.util.*;


public class Solution2 {
    public static int solution(int cacheSize, String[] cities) {
        // city가 cache에 없는 경우에는 전부다 cache miss이다.
        if (cacheSize == 0) {
            return cities.length * 5;
        }

        // cities의 요소를 저장하기 위한 cache공간으로 LinkedHashMap을 사용한다.
        Map<String, String> cache = MyLinkedHashMap.newInstance(cacheSize);

        // 최초실행시간을 0으로 초기화한다.
        int executionTime = 0;

        // 대소문자를 구분하지 않으므로 전부다 대문자로 바꾸어 놓는다.
        for (String city : cities) {
            city = city.toUpperCase();

            // 만약에 city가 cache안에 있다면 cache hit이다.
            if (cache.containsKey(city)) {
                executionTime += 1;
            }
            // city가 cache안에 없는 경우: 애당초 없었던 경우, 꽉차서 없었던 경우
            else {
                executionTime += 5;
                // city는 key이고 null은 value이다.
                cache.put(city, "None");
                Set<Map.Entry<String, String>> x = cache.entrySet();
                System.out.println(x);
            }
        }

        return executionTime;
    }

    public static void main(String[] args) {
        Solution2 s = new Solution2();
        int cacheSize =3;
        String[] cities={"Seoul", "Ulsan", "Busan", "Ulsan","Seoul"};

        System.out.println(solution(cacheSize, cities));
    }
}

class MyLinkedHashMap<K, V> extends LinkedHashMap<String, String> {
    private int cacheSize;

    public MyLinkedHashMap(int cacheSize) {
        super(cacheSize, 0.75f, true);
        this.cacheSize = cacheSize;
    }

    public static<K,V> MyLinkedHashMap<String, String> newInstance(int cacheSize) {
        return new MyLinkedHashMap<String, String>(cacheSize);

    }


    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
        return this.size() > cacheSize;
    }


}

 

 

 

최종적인 정답 → cache에 존재해도 지우고, 없어도 지우고

import java.util.ArrayList;

class Solution {
    public static int solution(int cacheSize, String[] cities) {
        int answer = 0;
        ArrayList<String> list = new ArrayList<String>();

        if (cacheSize == 0)
            return cities.length * 5;

        for (int i = 0; i < cities.length; i++) {
            cities[i] = cities[i].toUpperCase();

            if (list.contains(cities[i])) {
                answer++;
                list.remove(cities[i]);
                list.add(cities[i]);
            } else {
                answer += 5;
                if (list.size() == cacheSize) {
                    list.remove(0);
                    list.add(cities[i]);
                }
                else 
                    list.add(cities[i]);
            }
        }
        return answer;
    }
}
저작자표시 비영리 변경금지 (새창열림)

'프로그래머스(자바) > LV.2(자바)' 카테고리의 다른 글

위장→replaceAll() : 요소 전부 +1하기, 요소 전부 곱하기★ +map함수이용(count)★  (1) 2022.12.27
괄호 회전하기★★ →List의 rotate()를 이용, String → 리스트  (1) 2022.12.27
N개의 최소 공배수→ 연쇄 법칙 (겹치지X) + stack이용  (0) 2022.12.24
끝말잇기→contains()★+words[i].charAt(words[i].length()-1)★  (0) 2022.12.24
짝지어 제거하기→'문자비교' == , "문자열비교" equals, peek()★★+크레인 인형뽑기와 유사  (0) 2022.12.24
    '프로그래머스(자바)/LV.2(자바)' 카테고리의 다른 글
    • 위장→replaceAll() : 요소 전부 +1하기, 요소 전부 곱하기★ +map함수이용(count)★
    • 괄호 회전하기★★ →List의 rotate()를 이용, String → 리스트
    • N개의 최소 공배수→ 연쇄 법칙 (겹치지X) + stack이용
    • 끝말잇기→contains()★+words[i].charAt(words[i].length()-1)★
    @@#@@
    @@#@@
    자바, 스프링, 알고리즘, 깃허브, 파이썬

    티스토리툴바