-
[프로그래머스/JAVA] 숫자 문자열과 영단어 (2021 카카오 채용연계형 인턴십 문제)Algorithm/Java 2024. 10. 29. 21:55
https://school.programmers.co.kr/learn/courses/30/lessons/81301
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
📌 문제 요약
- 문자열 s에서 숫자가 포함된 부분은 그대로 두고, 영단어로 표현된 숫자를 실제 숫자로 변환해야 한다.
- 예: "one4seveneight" → 1478, "23four5six7" → 234567
[ 오답 노트 ]
❌ 기존 오답 코드해시맵을 사용해 접근하려 했지만 틀렸다 ㅜ
import java.util.*; class Solution { public int solution(String s) { String answer = ""; HashMap<Integer,String> hm = new HashMap<>(); hm.put(0, "zero"); hm.put(1, "one"); hm.put(2, "two"); hm.put(3, "three"); hm.put(4, "four"); hm.put(5, "five"); hm.put(6, "six"); hm.put(7, "seven"); hm.put(8, "eight"); hm.put(9, "nine"); // 한글자씩 점검?? for(int i = 0; i < s.length(); i++) { for(Map.Entry<Integer, String> entry : hm.entrySet()) { // 숫자라면? if(s.charAt(i) == entry.getKey()) { answer += s.charAt(i); } // 문자라면? if(s.contains(entry.getValue())) { answer += entry.getKey(); } } } return Integer.parseInt(answer); } }
📌 기존 코드의 문제점1. char와 Integer의 비교
if (s.charAt(i) == entry.getKey())
s.charAt()는 char 타입이고 entry.getKey()는 Integer 타입이므로 타입이 달라 항상 false가 반환된다
2. s.contains(entry.getValue())의 비효율성
if (s.contains(entry.getValue()))
- s.contains()는 문자열에 특정 값이 포함되어 있는지만 확인한다
- 하지만 변환 과정에서 이미 처리된 문자열 부분을 다시 확인하거나, 처리 순서를 보장하지 못한다
3. answer에 잘못된 값이 누적
- 변환된 숫자를 제대로 관리하지 않아 중복되거나 엉뚱한 값이 누적될 가능성이 크다
- 처리한 부분을 문자열 s에서 제거하거나 대체하지 않으므로 변환이 정확히 이루어지지 않는다
4. 중첩된 for 루프 사용
- 문자열의 각 문자마다 모든 숫자와 영단어를 반복적으로 비교하므로 매우 비효율적이다
- 입력 길이가 길어지면 성능 문제가 발생할 가능성이 크다
[ 정답 코드 & 올바른 풀이 ]
📌 올바른 풀이m1) 해시맵으로 푸는 방법
문자열을 한 글자씩 탐색하며 영단어를 누적(temp)하여 숫자로 변환한다
m2) 해시맵 사용하지 않고 더 간단한 코드로 구현
- 문자열에서 숫자 영단어를 숫자로 순서대로 대체한다.
- 문자열 치환을 반복적으로 수행하여 영단어를 모두 변환
📌 정답 코드m1) 해시맵으로 구현
import java.util.*; // m1) 해시맵 사용 방법 class Solution { public int solution(String s) { // String은 불변이므로 StringBuilder를 사용하는게 성능 측면에서 유리 StringBuilder answer = new StringBuilder(); StringBuilder temp = new StringBuilder(); // 영단어를 누적할 문자열 HashMap<String, Integer> hm = new HashMap<>(); hm.put("zero", 0); hm.put("one", 1); hm.put("two", 2); hm.put("three", 3); hm.put("four", 4); hm.put("five", 5); hm.put("six", 6); hm.put("seven", 7); hm.put("eight", 8); hm.put("nine", 9); // 한글자씩 점검 for(int i = 0; i < s.length(); i++) { char c = s.charAt(i); // 1.숫자인 경우 // 문자가 숫자인지 판단하는 함수인 Character.isDigit()를 사용 if(Character.isDigit(c)) { answer.append(c); // 2.문자인 경우 }else { temp.append(c); // z -> ze -> zer -> zero // temp가 영단어와 매핑되면 숫자로 변환 // (temp를 toString활용해서 문자열로 변환) if(hm.containsKey(temp.toString())) { answer.append(hm.get(temp.toString())); temp.setLength(0); // temp 초기화 } } } return Integer.parseInt(answer.toString()); } }
m2) 해시맵 사용하지 않고 배열로 구현
class Solution { public int solution(String s) { // 영단어 배열 정의 String[] words = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; // 문자열에서 영단어를 순차적으로 숫자로 변환 for(int i = 0; i < words.length; i++) { // 문자열 .replace() 활용해 문자열 포함된 기존 문자를 바꿀 문자로 변환 s = s.replace(words[i], String.valueOf(i)); } return Integer.parseInt(s); } }
반응형'Algorithm > Java' 카테고리의 다른 글
[프로그래머스/JAVA] 콜라 문제 (0) 2024.10.30 [프로그래머스/JAVA] 문자열 내 마음대로 정렬하기 (0) 2024.10.29 [프로그래머스/JAVA] 두 개 뽑아서 더하기 (0) 2024.10.29 [프로그래머스/JAVA] 최대공약수와 최소공배수 (0) 2024.10.28 [백준/JAVA] 2231번 : 분해합 (0) 2024.10.28