• 카테고리

    질문 & 답변
  • 세부 분야

    알고리즘 · 자료구조

  • 해결 여부

    미해결

중복된 문자 제거 코드

24.04.19 10:03 작성 조회수 28

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

c++코드를 자바로 변형했는데, 해시맵 오류가 뜹니다.
잘못 변형한 곳이 어디인지 궁금합니다.

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

public class Main {
    public static void main(String[] argvs) {
        Scanner sc = new Scanner(System.in);
        
        String s=sc.next();
        s=s.toUpperCase();
        LinkedList<Character> res = new LinkedList<>();
        
        HashMap<Character, Integer> map = new HashMap<>();
        for(char x : s.toCharArray()) {
        	map.put(x, map.getOrDefault(x, 0)+1);
        }
        
        for(char x : map.keySet()) {
        	System.out.println(x+": "+map.get(x));
        }
        HashMap<Character, Integer> ch = new HashMap<>();
        
        for(char x: s.toCharArray()) {
        	map.put(x, map.get(x)-1);
        	if(ch.get(x)==1) continue;
        	while(res.size()!=0 && res.peekLast()>x && map.get(res.peekLast())>0) {
        		ch.put(res.peekLast(),ch.get(res.peekLast()-1));
        		//if(ch.get(res.peekLast())==0) ch.remove(res.peekLast());
        		res.pollLast();
        	}
        	res.addLast(x);
        	ch.put(x, ch.get(x)+1);
        }
        for(int i=0; i<res.size(); i++) System.out.print(res.get(i));
    }
}

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.21

안녕하세요, 인프런 AI 인턴입니다.

xogh7532님, 코드를 살펴본 결과 중복된 문자를 제거하는 로직에서 몇 가지 오류를 발견하였습니다.

  1. ch.get(x)==1 이 조건은 ch 맵에 x가 1인 경우 계속 넘어가는 로직인데, 처음 ch 맵에 값을 넣기 전에는 ch.get(x) 결과가 null이므로 NullPointerException을 발생시킬 수 있습니다. 따라서 if(ch.getOrDefault(x, 0) == 1) continue;로 변경하는 것이 좋습니다.

  2. ch.put(res.peekLast(),ch.get(res.peekLast()-1)); 이 부분은 개념적으로 오류가 있습니다. ch.get(res.peekLast()-1)CharacterInteger를 연산하는 것으로 논리적으로 맞지 않습니다. 목적을 정확히 파악하기 어렵지만, 만약 res.peekLast()의 횟수를 1 감소시키고자 한다면, 이 줄은 제거하고 ch.put(res.peekLast(), ch.get(res.peekLast()) - 1);로 바꾸어야 합니다.

  3. 주석 처리된 if(ch.get(res.peekLast())==0) ch.remove(res.peekLast());에 대하여, 사용하지 않는 키를 삭제하고자 한다면 해당 코드 위에 ch.put 문장을 수정 후 주석을 해제해도 됩니다.

  4. 마지막으로, 각 문자를 추가할 때 ch.put(x, ch.get(x)+1); 이 부분에서 ch.get(x)null일 수 있으므로 ch.put(x, ch.getOrDefault(x, 0) + 1);로 변경해야 합니다.

코드 수정 후 예시는 다음과 같습니다:

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

public class Main {
    public static void main(String[] argvs) {
        Scanner sc = new Scanner(System.in);

        String s=sc.next();
        s=s.toUpperCase();
        LinkedList<Character> res = new LinkedList<>();

        HashMap<Character, Integer> map = new HashMap<>();
        for(char x : s.toCharArray()) {
        	map.put(x, map.getOrDefault(x, 0)+1);
        }

        for(char x : map.keySet()) {
        	System.out.println(x+": "+map.get(x));
        }
        HashMap<Character, Integer> ch = new HashMap<>();

        for(char x: s.toCharArray()) {
            map.put(x, map.get(x)-1);
            if(ch.getOrDefault(x, 0) == 1) continue;
            while(res.size() != 0 && res.peekLast() > x && map.get(res.peekLast()) > 0) {
                char last = res.peekLast();
                ch.put(last, ch.get(last) - 1);
                //if(ch.get(last) == 0) ch.remove(last);
                res.pollLast();
            }
            res.addLast(x);
            ch.put(x, ch.getOrDefault(x, 0) + 1);
        }
        for(int i=0; i<res.size(); i++) System.out.print(res.get(i));
    }
}

이 수정사항을 적용하면 해시맵 관련 오류를 해결할 수 있습니다.