문제
주어진 로마 숫자의 합을 정수와 로마 숫자로 출력하는 문제
아이디어
🔸로마문자 to 정수 : 해시맵 이용
순방향의 경우 바로 정수로 바꾸고, 역방향의 경우 다음 문자와 결합하여 정수로 바꿈
마지막 문자는 바로 정수로 바꿈
주어진 로마자가 하나인 경우 구현한 방향 로직을 실행할 수 없으므로 따로 빼주어서 바로 정수로 바꿈
🔸정수 to 로마문자 : 배열 2개 이용
키를 기준으로 정렬된 해시맵을 구현하기 위해서 정적배열 2개 이용
각 인덱스끼리 매핑되게 하면, '정렬된 해시맵'처럼 사용할 수 있음
while 문을 돌면서 num가 최소한의 문자로 바뀔 수 있게 함
헷갈렸던 부분 : 노란색으로 표시한 'V,C,D는 한번만 사용할 수 있고, I, X,C,M은 연속 세번까지만 사용 가능', 'IX와 IV는 같이 쓸 수 없음' 등의 조건을 어떻게 구현해야할지 고민했지만 생각해보면, 큰 수부터 로마자로 바꾸면 발생할 수 없는 조건이기 때문에 구현하지 않아도 되는 것이었음
package javaPractice.BJ2608;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class Main {
public static int romeToInt(String[] r1){
HashMap<String, Integer> hm = new HashMap<>();
{
hm.put("I", 1);
hm.put("V", 5);
hm.put("X", 10);
hm.put("L", 50);
hm.put("C", 100);
hm.put("D", 500);
hm.put("M", 1000);
hm.put("IV", 4);
hm.put("IX", 9);
hm.put("XL", 40);
hm.put("XC", 90);
hm.put("CD", 400);
hm.put("CM", 900);
}
if(r1.length == 1){
return hm.get(r1[0]);
}
int result = 0;
// 로직은 좋으나 r1가 한자리수인 경우 실행되지 않으므로 따로 처리해줘야 함
for (int i = 0; i < r1.length-1; i++) {
if(hm.get(r1[i]) >= hm.get(r1[i+1])){ // 순방향이면 그대로 정수로 바꾸기
result += hm.get(r1[i]);
} else {
result += hm.get((r1[i])+r1[i+1]); // 역방향이면 다음 수랑 결합한 것을 정수로 바꾸기
i++;
}
if(i == r1.length-2){
result += hm.get(r1[r1.length-1]); // 마지막 idx에 도달하면 그대로 정수로 바꾸기
}
}
return result;
}
public static String intToRome(int num){
StringBuilder result = new StringBuilder();
// 해시맵을 이용하려 했으나, 해시맵은 정렬을 보장하지 않으므로 크기 순서대로 꺼낼 수 없다는 단점이 있음
// => 두개의 배열을 이용하면 됨
// 내가 정적 배열 두개를 만들 수 있고, 각 인덱스가 매핑되게 하면, '키를 기준으로 정렬된 해시맵'처럼 사용할 수 있는 것!
String[] rome = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
int i = 0;
while(num > 0){
while(num >= values[i]){
num-=values[i];
result.append(rome[i]);
}
i++;
}
return result.toString();
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] r1 = bf.readLine().split("");
String[] r2 = bf.readLine().split("");
int sum = romeToInt(r1) + romeToInt(r2);
String result = intToRome(sum);
System.out.println(sum);
System.out.println(result);
}
}
'Algorithm > 알고리즘 문제' 카테고리의 다른 글
백준 5397번 : 키로거 (0) | 2023.06.25 |
---|---|
백준 1406번 : 에디터 (0) | 2023.06.24 |
[프로그래머스] 숫자 문자열과 영단어 (0) | 2023.05.23 |
백준 1158번 : 요세푸스 문제 (0) | 2023.05.16 |
백준 26008번 : 해시 해킹 (1) | 2023.05.15 |