반응형
◎ 문제풀이
문제가 복잡해 보이나 이해를 하면 어려운 문제는 아니다. 복잡한 개념이 들어가 있지는 않으나 구현력이 필요한 문제였다.
크게 두 가지 과정이 있다.
1) 로마 숫자를 십진법 숫자로 만들기
2) 십진법 숫자를 로마숫자로 만들기
- 로마 숫자를 십진법 숫자로 만들기
1) 로마문자와 십집법 숫자가 매핑된 Map 자료구조를 만든다.
2) 로마숫자를 좌측부터 한 문자씩 읽어온다.
3) 현재 문자는 이전 문자보다 작아야 한다.
4) 현재 문자가 이전 문자보다 크다면 XL, XC , CD ,CM ... 이런 문자이다.
5) 각 문자를 Map 자료구조의 key값으로 넣어 십진법 숫자를 가져와 합친다.
- 십진법 숫자를 로마숫자로 만들기
1) 십진법 숫자와 로마문자가 매핑된 Map 자료구조를 만든다.
2) 1000의 자리부터 1의 자리까지 각 자리의 수를 가져온다.
3) 9, 4인 경우는 XL, XC , CD ,CM ... 이런 문자이고 5보다 큰 경우와 5보다 작은 경우로 나눈다.
예를들어,
100의 자리가 7이라고 해보자.
7은 5보다 크다. 합으로 표현하면 5 + 1 + 1 이다. 이는 DCC 이다.
만약 3이라면
1 + 1 + 1이다. 이는 CCC이다.
만약 4라면
100의 자리의 4는 CD이다.
이런 원리로 각 자리의 수를 로마문자로 변환해준다.
4) 자릿수에 매핑되는 로마문자를 합쳐 문자열을 만든다.
◎ 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
//BOJ2608 로마숫자
public class Main {
static Map<String,Integer> RomeToNumMap = new HashMap<>();
static Map<Integer,String> NumToRomeMap = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
init();
String value1 = br.readLine();
String value2 = br.readLine();
// 로마문자를 십진법으로 변환하기
int num1 = convertRomeNumToDecimal(value1);
int num2 = convertRomeNumToDecimal(value2);
int sum = num1 + num2;
// 십진법을 로마문자로 변환하기
String ans = convertDecimalToRomeNum(sum);
// 출력
System.out.println(sum);
System.out.println(ans);
}
public static void init(){
// 로마숫자 -> 십집법 Map 자료구조
RomeToNumMap.put("I",1);
RomeToNumMap.put("V",5);
RomeToNumMap.put("X",10);
RomeToNumMap.put("L",50);
RomeToNumMap.put("C",100);
RomeToNumMap.put("D",500);
RomeToNumMap.put("M",1000);
RomeToNumMap.put("IV",4);
RomeToNumMap.put("IX",9);
RomeToNumMap.put("XL",40);
RomeToNumMap.put("XC",90);
RomeToNumMap.put("CD",400);
RomeToNumMap.put("CM",900);
// 십진법 숫자 -> 로마숫자 Map 자료구조
NumToRomeMap.put(1,"I");
NumToRomeMap.put(5,"V");
NumToRomeMap.put(10,"X");
NumToRomeMap.put(50,"L");
NumToRomeMap.put(100,"C");
NumToRomeMap.put(500,"D");
NumToRomeMap.put(1000,"M");
NumToRomeMap.put(4,"IV");
NumToRomeMap.put(9,"IX");
NumToRomeMap.put(40,"XL");
NumToRomeMap.put(90,"XC");
NumToRomeMap.put(400,"CD");
NumToRomeMap.put(900,"CM");
}
// 로마숫자를 십진법 숫자로 변경
public static int convertRomeNumToDecimal(String romeNum){
int decimal = 0;
String before = null;
for(int i =0; i<romeNum.length();i++){
String curr = String.valueOf(romeNum.charAt(i));
if(before == null) before = curr; // 이전문자가 null인 경우
else if(RomeToNumMap.get(before) >= RomeToNumMap.get(curr)) { // 이전문자가 현재문자보다 큰 경우
decimal += RomeToNumMap.get(before);
before = curr;
}else{
decimal += RomeToNumMap.get(before.concat(curr)); // 이전문자가 현재문자보다 작은 경우
before = null;
}
}
if(before != null ){ // 마지막 문자
decimal += RomeToNumMap.get(before);
}
return decimal;
}
// 십진법 숫자를 로마 숫자로 변경
public static String convertDecimalToRomeNum(int decimal){
String ans = "";
int digit = 1000;
while(true){
int m = decimal/digit;
decimal -= m*digit;
ans = convert(ans,m,digit);
if(digit==1) break;
digit = digit/10;
}
return ans;
}
// 각 자리수에 맞는 로마숫자로 변경
private static String convert(String ans, int m, int digit) {
if( m == 9 ) ans += NumToRomeMap.get(9*digit);
else if( m == 4 ) ans += NumToRomeMap.get(4*digit);
else if ( m >= 5 ) {
m -= 5;
ans += NumToRomeMap.get(5*digit);
while(m-- > 0){
ans += NumToRomeMap.get(digit);
}
}
else{
while(m-- > 0){
ans += NumToRomeMap.get(digit);
}
}
return ans;
}
}
반응형
'문제풀이 > String' 카테고리의 다른 글
[PS] BOJ9081 단어 맞추기 ( string ) with JAVA (0) | 2023.09.20 |
---|---|
[PS] BOJ17609 회문 ( string ) with JAVA (0) | 2023.09.01 |
[PS] BOJ165000 문자열 판별 ( String ) with JAVA (0) | 2023.08.23 |
[CodingTest] BOJ17413 단어뒤집기2 ( 문자열 ) with Python (0) | 2023.06.09 |
[JAVA] 백준 1436번 영화감독 숌 : 문자열 찾기 (0) | 2021.07.31 |