codekata6. 로마자
로마자에서 숫자로 바꾸기 1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.
문제 파악
요구사항 : 로마자를 숫자로 반환해서 줘라.
제한 사항 : IV, IX 등등 로마자의 계산체계
인풋 : 로마자를 표현한 string값
아웃풋 : 숫자값
본질 : 딕셔너리의 key로 값을 가져오는 성질. 그리고 제한사항에 대한 조건문.
생각하는 과정
-
리스트의 각 문자를 숫자값으로 바꾼다?
-
IX같은 경우는 어떻게 할거야? 반복문에서 바로 하기엔 무리가 있다.
-
자릿수는 어떻게 할거야? X이전에 오는 I는 X보다 크잖아.
-
리스트로 만들자! IX, I, X, 이렇게 의미가 확실히 구분되는 문자들끼리. 아니, 자릿수끼리.
첫번째 방법
by 예랑님.
1. 딕셔너리 정의 : 로마자의 특이한 부분들과, 모든 로마자를 각각 딕셔너리로 만든다.
2. 반복문 : rome_1의 각 문자에 대해서
3. 반복문 안의 반복문 : 해당 문자가 인풋값에 있는 경우에 대해서
4. 딕셔너리 접근 : 여기서 딕셔너리의 키는 곧 로마문자이고 value는 곧 그 문자가 뜻하는 값이므로, 이렇게. (딕셔너리의 items메서드도 알게 됐다. enumerate의 딕셔너리 버전.)
5. += : result에 차곡차곡 그 값을 더한다.
6. replace : 해당 문자를 빈 str값으로 바꾼다. 즉, 없앤다.
- 반복문의 순서가 중요하다. 만약 rome_2부터 반복문을 실행한다면 rome_2의 문자들을 찾아볼 수 없음.
- 일반적인 문자들에 대해서도 반복문 실행. 앞의 반복문과 비슷하다.
- return : 결과값을 반환한다.
def roman_to_num(s):
result = 0
rome_1 = {
‘IV’: 4, ‘IX’: 9,
‘XL’: 40, ‘XC’: 90,
‘CD’: 400, ‘CM’: 900,
}
rome_2 = {
‘I’: 1, ‘V’: 5, ‘X’: 10,
‘L’: 50, ‘C’: 100, ‘D’: 500, ‘M’: 1000,
}
for rome in rome_1:
while rome in s:
result += rome_1[rome]
s = s.replace(rome, ‘’, 1)
for rome in rome_2:
while rome in s:
result += rome_2[rome]
s = s.replace(rome, ‘’, 1)
print(‘result: ’, result)
return result
두번째 방법
by (최)준영님.
첫번째 방법과 접근방식이 살짝 다르다. 로마자의 특이한 문자들의 패턴을 읽은 것 같다.
- 딕셔너리 정의 : 일반적인 문자들에 대해서만
- 반복문 실행 : range(인풋값 길이 -1)에 대해서
- 조건문 : 여기서 패턴이 나온다. 해당 문자가 다음 index의 문자보다 작을 경우, 즉 첫번째 방법에서 정의한 rome_1의 문자들의 경우에는 결과값에서 해당 문자의 값을 뺀다.
아닐경우, 해당 문자의 값을 계속 더해나간다. - 마지막 index의 값을 더한다. (i+1번째로 접근하는 부분이 index error을 야기하기 때문)
- return : 결과값 반환
def roman_to_num(s):
all_roman = {
"I":1,
"V":5,
"X":10,
"L":50,
"C":100,
"D":500,
"M":1000
}
result= 0
for i in range(len(s) - 1):
current_one = all_roman[s[i]]
print(current_one)
next_one = all_roman[s[i+1]]
if current_one < next_one:
result -= current_one
else:
result += current_one
result += all_roman[s[-1]]
print(result)
return result
roman_to_num("XXVII")
세번째 방법
by 동명님.
두번째와 접근방식이 비슷하다. 그러나 reversed와 집합을 쓴 점이 다르다.
def roman_to_num(s):
romans = {
"I":1,
"V":5,
"X":10,
"L":50,
"C":100,
"D":500,
"M":1000
}
seen = set()
result = 0
for c in reversed(s):
if c not in seen:
seen.add(c)
if c == "V" or c =="X":
romans["I"] = -1
elif c == "L" or c == "C":
romans["X"] = -10
elif c == "D" or c == "M":
romans["C"] = -100
result += romans[c]
return result
roman_to_num("XXVII")
생각과 질문
- 문제 파악이 문제 해결의 50%를 차지하는 것 같다. 난 로마자 자체를 이상하게 이해해서, 접근방식도 이상해질 수 밖에 없었다.
Author And Source
이 문제에 관하여(codekata6. 로마자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@wonseok2877/codekata6저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)