Check if an input is a valid roman numeral

后端 未结 5 609
醉话见心
醉话见心 2021-01-14 10:46

I got a program that converts Roman numerals to integers and vice versa. My problem is that I don´t really know how to create a function that checks if the user input is a v

相关标签:
5条回答
  • 2021-01-14 11:01

    Call romantoint after the for loop

     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)
    
    0 讨论(0)
  • 2021-01-14 11:03

    Apart from the design problems that have already been pointed out, I'd like to just answer the question why your for-loop doesn't go through all the numerals

    If the entries are considered valid by your code, then the loop goes into the elif clause where it calls romanToInt(numeral)and then break. There's your problem: break take that out.

    Illustration: As soon as condition is met in this example, the loop will stop going through i in list

    for i in list:
       # do something
       if condition:
           break # "Stop the innermost loop now!"
    
    0 讨论(0)
  • 2021-01-14 11:05

    Instead of looping, you can convert both input and valid literals to sets and then substract them:

    def checkIfRomanNumeral(numeral):
        numeral = {c for c in numeral.upper()}
        validRomanNumerals = {c for c in "MDCLXVI()"}
        return not numeral - validRomanNumerals
    

    Returns True if numeral is valid, False otherwise. (Assuming that the empty string is valid)

    0 讨论(0)
  • 2021-01-14 11:13

    Writing a converter from ints to Romans is a standard interview question. I once wrote the following bi-directional implementation (toString-- decimal to Roman; parse -- Roman to decimal). The implementaion saticifies a number of additional criteria on the representation of Roman numbers, which are not obligatory, but generally followed:

    '''
    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
    
    0 讨论(0)
  • 2021-01-14 11:18
    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
    

    Returns a boolean whether the given 'numeral' is roman numeral or not.

    0 讨论(0)
提交回复
热议问题