Check if an input is a valid roman numeral
我有一个程序可以把罗马数字转换成整数,反之亦然。我的问题是我不知道如何创建一个函数来检查用户输入是否是有效的罗马数字。我的代码:
1 2 3 4 5 6 7 8 9 10 11 | def checkIfRomanNumeral(numeral): """Controls that the userinput only contains valid roman numerals""" numeral = numeral.upper() validRomanNumerals = ["M","D","C","L","X","V","I","(",")"] for letters in numeral: if letters not in validRomanNumerals: print("Sorry that is not a valid roman numeral") return True elif letters in validRomanNumerals: romanToInt(numeral) break |
我认为现在的问题是函数只检查输入(数字)中的第一个字母,因为for循环。如果输入的任何字母不是罗马数字,有人能帮我检查整个输入和打印功能吗("对不起,这不是一个有效的罗马数字")。列表中的括号validromanumerals用于转换大于4000的数字,因此它们必须存在。
写一个从英特到罗马人的转换是一个标准的面试问题。我曾经编写过以下双向实现(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | ''' Created on Feb 7, 2013 @author: olegs ''' ROMAN_CONSTANTS = ( ("","I","II","III","IV","V","VI","VII","VIII","IX" ), ("","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" ), ("","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" ), ("","M","MM","MMM","", "", "-", "", "", "" ), ) ROMAN_SYMBOL_MAP = dict(I=1, V=5, X=10, L=50, C=100, D=500, M=1000) CUTOFF = 4000 BIG_DEC = 2900 BIG_ROMAN ="MMCM" ROMAN_NOUGHT ="nulla" def digits(num): if num < 0: raise Exception('range error: negative numbers not supported') if num % 1 != 0.0: raise Exception('floating point numbers not supported') res = [] while num > 0: res.append(num % 10) num //= 10 return res def toString(num, emptyZero=False): if num < CUTOFF: digitlist = digits(num) if digitlist: res = reversed([ ROMAN_CONSTANTS[order][digit] for order, digit in enumerate(digitlist) ]) return"".join(res) else: return"" if emptyZero else ROMAN_NOUGHT else: if num % 1 != 0.0: raise Exception('floating point numbers not supported') # For numbers over or equal the CUTOFF, the remainder of division by 2900 # is represented as above, prepended with the multiples of MMCM (2900 in Roman), # which guarantees no more than 3 repetitive Ms. return BIG_ROMAN * (num // BIG_DEC) + toString(num % BIG_DEC, emptyZero=True) def parse(numeral): numeral = numeral.upper() result = 0 if numeral == ROMAN_NOUGHT.upper(): return result lastVal = 0 lastCount = 0 subtraction = False for symbol in numeral[::-1]: value = ROMAN_SYMBOL_MAP.get(symbol) if not value: raise Exception('incorrect symbol') if lastVal == 0: lastCount = 1 lastVal = value elif lastVal == value: lastCount += 1 # exceptions else: result += (-1 if subtraction else 1) * lastVal * lastCount subtraction = lastVal > value lastCount = 1 lastVal = value return result + (-1 if subtraction else 1) * lastVal * lastCount |
号
您可以将输入和有效的文本转换为集合,然后对它们进行减法运算,而不是循环:
1 2 3 4 | def checkIfRomanNumeral(numeral): numeral = {c for c in numeral.upper()} validRomanNumerals = {c for c in"MDCLXVI()"} return not numeral - validRomanNumerals |
如果
除了已经指出的设计问题外,我想回答一个问题,为什么你的for循环没有通过所有的数字
如果您的代码认为这些条目有效,那么循环将进入
图:只要满足本例中的条件,循环将停止通过
1 2 3 4 | for i in list: # do something if condition: break #"Stop the innermost loop now!" |
。
1 2 3 4 5 6 7 8 9 10 11 | def checkIfRomanNumeral(numeral): """Controls that the userinput only contains valid roman numerals""" numeral = numeral.upper() validRomanNumerals = ["M","D","C","L","X","V","I","(",")"] valid = True for letters in numeral: if letters not in validRomanNumerals: print("Sorry that is not a valid roman numeral") valid = False break return valid |
返回一个布尔值"数字"是否为罗马数字。
在
1 2 3 4 5 6 7 8 9 | def checkIfRomanNumeral(numeral): """Controls that the userinput only contains valid roman numerals""" numeral = numeral.upper() validRomanNumerals = ["M","D","C","L","X","V","I"] for letters in numeral: if letters not in validRomanNumerals: print("Sorry that is not a valid roman numeral") return False romanToInt(numeral) |