Python 将整数转换为罗马数字的基本程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28777219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:44:52  来源:igfitidea点击:

Basic program to convert integer to Roman numerals?

python

提问by skybreaker

I'm trying to write a code that converts a user-inputted integer into its Roman numeral equivalent. What I have so far is:

我正在尝试编写一个代码,将用户输入的整数转换为其等效的罗马数字。到目前为止我所拥有的是:

screenshot of my code

我的代码截图

The point of the generate_all_of_numeralfunction is so that it creates a string for each specific numeral. For example, generate_all_of_numeral(2400, 'M', 2000)would return the string 'MM'.

generate_all_of_numeral函数的重点是为每个特定数字创建一个字符串。例如,generate_all_of_numeral(2400, 'M', 2000)将返回字符串'MM'

I'm struggling with the main program. I start off finding the Roman numeral count for M and saving that into the variable M. Then I subtract by the number of M's times the symbol value to give me the next value to work with for the next largest numeral.

我正在努力处理主程序。我首先找到 M 的罗马数字计数并将其保存到变量 M 中。然后我减去 M 的次数乘以符号值,得到下一个值来处理下一个最大的数字。

Any nod to the right direction? Right now my code doesn't even print anything.

向正确的方向点头?现在我的代码甚至没有打印任何东西。

采纳答案by Jerome Montino

One of the best ways to deal with this is using the divmodfunction. You check if the given number matches any Roman numeral from the highest to the lowest. At every match, you should return the respective character.

处理此问题的最佳方法之一是使用该divmod函数。您检查给定的数字是否与从最高到最低的任何罗马数字匹配。在每场比赛中,您都应该返回相应的字符。

Some numbers will have remainders when you use the modulo function, so you also apply the same logic to the remainder. Obviously, I'm hinting at recursion.

当您使用模函数时,有些数字会有余数,因此您也可以对余数应用相同的逻辑。显然,我在暗示递归。

See my answer below. I use an OrderedDictto make sure that I can iterate "downwards" the list, then I use a recursion of divmodto generate matches. Finally, I joinall generated answers to produce a string.

看我下面的回答。我使用 anOrderedDict来确保我可以“向下”迭代列表,然后我使用递归divmod来生成匹配。最后,我join都生成了答案以生成一个字符串。

from collections import OrderedDict

def write_roman(num):

    roman = OrderedDict()
    roman[1000] = "M"
    roman[900] = "CM"
    roman[500] = "D"
    roman[400] = "CD"
    roman[100] = "C"
    roman[90] = "XC"
    roman[50] = "L"
    roman[40] = "XL"
    roman[10] = "X"
    roman[9] = "IX"
    roman[5] = "V"
    roman[4] = "IV"
    roman[1] = "I"

    def roman_num(num):
        for r in roman.keys():
            x, y = divmod(num, r)
            yield roman[r] * x
            num -= (r * x)
            if num <= 0:
                break

    return "".join([a for a in roman_num(num)])

Taking it for a spin:

试一试:

num = 35
print write_roman(num)
# XXXV

num = 994
print write_roman(num)
# CMXCIV

num = 1995
print write_roman(num)
# MCMXCV

num = 2015
print write_roman(num)
# MMXV

回答by Gotrank

You have to make the symbolCount a global variable. And use () in print method.

您必须使 symbolCount 成为一个全局变量。并在打印方法中使用 ()。

回答by bgnalm

When you use the def keyword, you just define a function, but you don't run it.

当您使用 def 关键字时,您只是定义了一个函数,而不是运行它。

what you're looking for is something more like this:

你正在寻找的是更像这样的东西:

def generate_all_numerals(n): 
...

def to_roman(n):
...

print "This program ..."
n = raw_input("Enter...")

print to_roman(n)

welcome to python :)

欢迎来到蟒蛇:)

回答by Rick Graves

The approach by Laughing Man works. Using an ordered dictionary is clever. But his code re-creates the ordered dictionary every time the function is called, and within the function, in every recursive call, the function steps through the whole ordered dictionary from the top. Also, divmod returns both the quotient and the remainder, but the remainder is not used. A more direct approach is as follows.

Laughing Man 的方法有效。使用有序字典很聪明。但是他的代码在每次调用函数时都会重新创建有序字典,并且在函数内,在每次递归调用中,函数从顶部逐步遍历整个有序字典。此外, divmod 返回商和余数,但不使用余数。更直接的方法如下。

def _getRomanDictOrdered():
    #
    from collections import OrderedDict
    #
    dIntRoman = OrderedDict()
    #
    dIntRoman[1000] = "M"
    dIntRoman[900] = "CM"
    dIntRoman[500] = "D"
    dIntRoman[400] = "CD"
    dIntRoman[100] = "C"
    dIntRoman[90] = "XC"
    dIntRoman[50] = "L"
    dIntRoman[40] = "XL"
    dIntRoman[10] = "X"
    dIntRoman[9] = "IX"
    dIntRoman[5] = "V"
    dIntRoman[4] = "IV"
    dIntRoman[1] = "I"
    #
    return dIntRoman

_dIntRomanOrder = _getRomanDictOrdered() # called once on import

def getRomanNumeralOffInt( iNum ):
    #
    lRomanNumerals = []
    #
    for iKey in _dIntRomanOrder:
        #
        if iKey > iNum: continue
        #
        iQuotient = iNum // iKey
        #
        if not iQuotient: continue
        #
        lRomanNumerals.append( _dIntRomanOrder[ iKey ] * iQuotient )
        #
        iNum -= ( iKey * iQuotient )
        #
        if not iNum: break
        #
    #
    return ''.join( lRomanNumerals )

Checking the results:

检查结果:

>>> getRomanNumeralOffInt(35)
'XXXV'
>>> getRomanNumeralOffInt(994)
'CMXCIV'
>>> getRomanNumeralOffInt(1995)
'MCMXCV'
>>> getRomanNumeralOffInt(2015)
'MMXV'

回答by Mohammad Mahjoub

 """
# This program will allow the user to input a number from 1 - 3999 (in english) and will translate it to Roman numerals.
# sources: http://romannumerals.babuo.com/roman-numerals-100-1000
Guys the reason why I wrote this program like that so it becomes readable for everybody. 
Let me know if you have any questions... 
"""
while True:
    try:
        x = input("Enter a positive integer from 1 - 3999 (without  spaces) and this program will translated to Roman numbers: ")
        inttX = int(x)
        if (inttX) == 0 or 0 > (inttX):
            print("Unfortunately, the  smallest number that you can enter is 1 ")
        elif (inttX) > 3999:
            print("Unfortunately, the  greatest number that you can enter is 3999")
        else:
            if len(x) == 1:
                if inttX == 1:
                    first = "I"
                elif inttX == 2:
                    first = "II"
                elif inttX == 3:
                    first = "III"
                elif inttX == 4:
                    first = "IV"
                elif inttX == 5:
                    first = "V"
                elif inttX == 6:
                    first = "VI"
                elif inttX == 7:
                    first = "VII"
                elif inttX == 8:
                    first = "VIII"
                elif inttX == 9:
                    first = "IX"
                print(first)
                break
            if len(x) == 2:
                a = int(x[0])
                b = int(x[1])
                if a == 0:
                    first = ""
                elif a == 1:
                    first = "X"
                elif a == 2:
                    first = "XX"
                elif a == 3:
                    first = "XXX"
                elif a == 4:
                    first = "XL"
                elif a == 5:
                    first = "L"
                elif a == 6:
                    first = "LX"
                elif a == 7:
                    first = "LXX"
                elif a == 8:
                    first = "LXXX"
                elif a == 9:
                    first = "XC"

                if b == 0:
                    first1 = "0"
                if b == 1:
                    first1 = "I"
                elif b == 2:
                    first1 = "II"
                elif b == 3:
                    first1 = "III"
                elif b == 4:
                    first1 = "IV"
                elif b == 5:
                    first1 = "V"
                elif b == 6:
                    first1 = "VI"
                elif b == 7:
                    first1 = "VII"
                elif b == 8:
                    first1 = "VIII"
                elif b == 9:
                    first1 = "IX"
                print(first + first1)
                break
            if len(x) == 3:
                a = int(x[0])
                b = int(x[1])
                c = int(x[2])
                if a == 0:
                    first12 = ""
                if a == 1:
                    first12 = "C"
                elif a == 2:
                    first12 = "CC"
                elif a == 3:
                    first12 = "CCC"
                elif a == 4:
                    first12 = "CD"
                elif a == 5:
                    first12 = "D"
                elif a == 6:
                    first12 = "DC"
                elif a == 7:
                    first12 = "DCC"
                elif a == 8:
                    first12 = "DCCC"
                elif a == 9:
                    first12 = "CM"

                if b == 0:
                    first = ""
                elif b == 1:
                    first = "X"
                elif b == 2:
                    first = "XX"
                elif b == 3:
                    first = "XXX"
                elif b == 4:
                    first = "XL"
                elif b == 5:
                    first = "L"
                elif b == 6:
                    first = "LX"
                elif b == 7:
                    first = "LXX"
                elif b == 8:
                    first = "LXXX"
                elif b == 9:
                    first = "XC"

                if c == 1:
                    first1 = "I"
                elif c == 2:
                    first1 = "II"
                elif c == 3:
                    first1 = "III"
                elif c == 4:
                    first1 = "IV"
                elif c == 5:
                    first1 = "V"
                elif c == 6:
                    first1 = "VI"
                elif c == 7:
                    first1 = "VII"
                elif c == 8:
                    first1 = "VIII"
                elif c == 9:
                    first1 = "IX"
                print(first12 + first + first1)
                break

            if len(x) == 4:
                a = int(x[0])
                b = int(x[1])
                c = int(x[2])
                d = int(x[3])
                if a == 0:
                    first1 = ""
                if a == 1:
                    first1 = "M"
                elif a == 2:
                    first1 = "MM"
                elif a == 3:
                    first1 = "MMM"

                if b == 0:
                    first12 = ""
                if b == 1:
                    first12 = "C"
                elif b == 2:
                    first12 = "CC"
                elif b == 3:
                    first12 = "CCC"
                elif b == 4:
                    first12 = "CD"
                elif b == 5:
                    first12 = "D"
                elif b == 6:
                    first12 = "DC"
                elif b == 7:
                    first12 = "DCC"
                elif b == 8:
                    first12 = "DCCC"
                elif b == 9:
                    first12 = "CM"

                if c == 0:
                    first3 = ""
                elif c == 1:
                    first3 = "X"
                elif c == 2:
                    first3 = "XX"
                elif c == 3:
                    first3 = "XXX"
                elif c == 4:
                    first3 = "XL"
                elif c == 5:
                    first3 = "L"
                elif c == 6:
                    first3 = "LX"
                elif c == 7:
                    first3 = "LXX"
                elif c == 8:
                    first3 = "LXXX"
                elif c == 9:
                    first3 = "XC"

                if d == 0:
                    first = ""
                elif d == 1:
                    first = "I"
                elif d == 2:
                    first = "II"
                elif d == 3:
                    first = "III"
                elif d == 4:
                    first = "IV"
                elif d == 5:
                    first = "V"
                elif d == 6:
                    first = "VI"
                elif d == 7:
                    first = "VII"
                elif d == 8:
                    first = "VIII"
                elif d == 9:
                    first = "IX"
                print(first1 + first12 + first3 + first)
                break
    except ValueError:
        print(" Please enter a positive integer! ")

回答by Aziz Alto

Here is another way, without division:

这是另一种没有除法的方法:

num_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
           (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]


def num2roman(num):

    roman = ''

    while num > 0:
        for i, r in num_map:
            while num >= i:
                roman += r
                num -= i

    return roman

# test 
>>> num2roman(2242)
'MMCCXLII'

Updatesee the execution visualized

更新查看可视化的执行

回答by user7122277

Only 1 - 999

只有 1 - 999

while True:

 num = input()
 def val(n):
    if n == 1:
        rom = 'I'
        return rom
    if n == 4:
        rom = 'IV'
        return rom
    if n == 5:
        rom = 'V'
        return rom
    if n == 9:
        rom = 'IX'
        return rom
    if n == 10:
        rom = 'X'
        return rom
    if n == 40:
        rom = 'XL'
        return rom
    if n == 50:
        rom = 'L'
        return rom
    if n == 90:
        rom = 'XC'
        return rom
    if n == 100:
        rom = 'C'
        return rom
    if n == 400:
        rom = 'CD'
        return rom
    if n == 500:
        rom = 'D'
        return rom
    if n == 900:
        rom = 'CM'
        return rom

 def lastdigit(num02):
    num02 = num % 10
    num03 = num % 5
    if 9 > num02 > 5:
        return str('V' + 'I'*num03)
    elif num02 < 4:
        return str('I'*num03)
    else:
        return str(val(num02))

 k3 = lastdigit(num)

 def tensdigit(num12):
    num12 = num % 100 - num % 10
    num13 = num % 50
    if 90 > num12 > 50:
        return str('L' + 'X'*(num13/10))
    elif num12 < 40:
        return str('X'*(num13/10))
    else:
        return str(val(num12))

 k2 = tensdigit(num)

 def hundigit(num112):
    num112 = (num % 1000 - num % 100)
    num113 = num % 500
    if 900 > num112 > 500:
        return str('D' + 'C'*(num113/100))
    elif num112 < 400:
        return str('C'*(num113/100))
    else:
        return str(val(num112))

 k1 = hundigit(num)

 print '%s%s%s' %(k1,k2,k3)

回答by Linus

Another way to do this. separating out processing of number starting with 4 , 9 and others. it can be simplified further

另一种方法来做到这一点。分离处理以 4 、 9 等开头的数字。它可以进一步简化

def checkio(data):
romans = [("I",1),("V",5),("X",10),("L",50),("C",100),("D",500),("M",1000)]
romans_rev = list(sorted(romans,key = lambda x: -x[1]))
def process_9(num,roman_str):
    for (k,v) in romans:
        if (v > num):
            current_roman = romans[romans.index((k,v))]
            prev_roman = romans[romans.index((k,v)) - 2]
            roman_str += (prev_roman[0] + current_roman[0])
            num -= (current_roman[1] - prev_roman[1])
            break
    return num,roman_str
def process_4(num,roman_str):
    for (k,v) in romans:
        if (v > num):
            current_roman = romans[romans.index((k,v))]
            prev_roman = romans[romans.index((k,v)) - 1]
            roman_str += (prev_roman[0] + current_roman[0])
            num -= (current_roman[1] - prev_roman[1])
            break
    return num,roman_str
def process_other(num,roman_str):
    for (k,v) in romans_rev:
        div = num // v
        if ( div != 0 and num > 0 ):
            roman_str += k * div
            num -= v * div
            break
    return num,roman_str
def get_roman(num):
    final_roman_str = ""
    while (num > 0):
        if (str(num).startswith('4')):
            num,final_roman_str = process_4(num,final_roman_str)
        elif(str(num).startswith('9')):
            num,final_roman_str = process_9(num,final_roman_str)
        else:
            num,final_roman_str = process_other(num,final_roman_str)
    return final_roman_str

return get_roman(data)


print(checkio(number))

回答by cardeol

This is my approach

这是我的方法

def itr(num):  
    dct = { 1: "I", 4: "IV", 5: "V", 9: "IX", 10: "X", 40: "XL", 50: "L", 90: "XC", 100: "C", 400: "CD", 500: "D", 900: "CM", 1000: "M" }
    if(num in dct):
        return dct[num]

    for i in [1000,100,10,1]:
        for j in [9*i, 5*i, 4*i, i]:
            if(num>=j):
                return itr(j) + itr(num-j) 

回答by Divyang Bissa

def test(num):

    try:
        if type(num) != type(1):
            raise Exception("expected integer, got %s" % type(num))
        if not 0 < num < 4000:
            raise Exception("Argument must be between 1 and 3999")
        ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
        nums = ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I')
        result = ""
        for i in range(len(ints)):
            count = int(num / ints[i])
            result += nums[i] * count
            num -= ints[i] * count
        print result
    except Exception as e:
        print e.message