1 Востаннє редагувалося A.N.Onim (13.07.2014 21:16:34)

Тема: Алгорит зміни числа с римського в арабський

Написав прогу котра змінює формат числа з арабського в римський.
Можна почитати тут.
Кому лінь переходити:

# _*_ coding: cp1251 _*_
# програма для зміни формату чисел: з арабського в римський

def arabic_roman(number):
    """
Функція змінює формат числа з арабського в римський.
Ліміт числа яке може змінити - 3999
    """ 

    number = str(number)
    const_dict = {'0':'', '1':'I', '2':'II', '3':'III', '4':'IV', '5':'V', \
                  '6':'VI', '7':'VII', '8':'VIII', '9':'IX', '10':'X', \
                  '50':'L', '100':'C', '500':'D', '1000':'M'}
    result_list = []
    result = ''
    if 0<=int(number)<=3999:
        if const_dict.has_key(number):
            result = const_dict[number]
        else:
            if len(number)>=2: # формує результат для одиниць і десятків
                result_list.append(const_dict[number[-1]])
                if number[-2]=='1':
                    result_list.append('X')
                elif number[-2]=='2':
                    result_list.append('XX')
                elif number[-2]=='3':
                    result_list.append('XXX')
                elif number[-2]=='4':
                    result_list.append('XL')
                elif number[-2]=='5':
                    result_list.append('L')
                elif number[-2]=='6':
                    result_list.append('LX')
                elif number[-2]=='7':
                    result_list.append('LXX')
                elif number[-2]=='8':
                    result_list.append('LXXX')
                elif number[-2]=='9':
                    result_list.append('XC')
            if len(number)>=3: # формує результат для сотень
                if number[-3]=='1':
                    result_list.append('C')
                if number[-3]=='2':
                    result_list.append('CC')
                if number[-3]=='3':
                    result_list.append('CCC')
                if number[-3]=='4':
                    result_list.append('CD')
                if number[-3]=='5':
                    result_list.append('D')
                if number[-3]=='6':
                    result_list.append('DC')
                if number[-3]=='7':
                    result_list.append('DCC')
                if number[-3]=='8':
                    result_list.append('DCCC')
                if number[-3]=='9':
                    result_list.append('CM')
            if len(number)==4: # формує результат для тисяч
                result_list.append('M'*int(number[-4]))
            result_list.reverse()
            result = ''.join(result_list) # результат переводиться в string
    return result
    

if __name__ == '__main__':
    number = raw_input('Input data, please:')
    result = arabic_roman(number)
    print result 

А як зробити щоб змінювало навпаки? Тобто алгоритм на словах. Я в пошуковиках шукав - є щось але вже у вигляді коду і то незрозумілого.
І якщо можна покритикуйте вище написану прогу  :) І чи не забагато коду до такої простой задачі?

2

Re: Алгорит зміни числа с римського в арабський

Гадаю, краще перенести тему в алгоритми.
Звісно, коду забагато. Ідея, н.м.д, має бути така: в циклі знаходимо найбільше число, яке нам підходить (вигляду {1,4,5,9}*10^n), додаємо до результату це число в римській нотації і віднімаємо його від аргументу. Псевдокод потрібен?
Зворотний алгоритм значно простіший, коли не треба перевіряти валідність - тоді просто розбираємо число на символи (окрім, хіба, випадків, кратних 4 і 9, але це теж нескладно) і додаємо. З перевіркою складніше, але ненабагато - треба просто пам'ятати останню перетворену цифру і слідкувати, щоб наступна не була більшою і щоб не було більше, ніж 3 поспіль 10^n чи одна інша цифра.

Подякували: A.N.Onim1

3

Re: Алгорит зміни числа с римського в арабський

"""Convert to and from Roman numerals"""

__author__ = "Mark Pilgrim (f8dy@diveintopython.org)"
__version__ = "1.4"
__date__ = "8 August 2001"
__copyright__ = """Copyright (c) 2001 Mark Pilgrim

This program is part of "Dive Into Python", a free Python tutorial for
experienced programmers.  Visit http://diveintopython.org/ for the
latest version.

This program is free software; you can redistribute it and/or modify
it under the terms of the Python 2.1.1 license, available at
http://www.python.org/2.1.1/license.html
"""

import re

#Define exceptions
class RomanError(Exception): pass
class OutOfRangeError(RomanError): pass
class NotIntegerError(RomanError): pass
class InvalidRomanNumeralError(RomanError): pass

#Define digit mapping
romanNumeralMap = (('M',  1000),
                   ('CM', 900),
                   ('D',  500),
                   ('CD', 400),
                   ('C',  100),
                   ('XC', 90),
                   ('L',  50),
                   ('XL', 40),
                   ('X',  10),
                   ('IX', 9),
                   ('V',  5),
                   ('IV', 4),
                   ('I',  1))

def toRoman(n):
    """convert integer to Roman numeral"""
    if not (0 < n < 5000):
        raise OutOfRangeError, "number out of range (must be 1..4999)"
    if int(n) != n:
        raise NotIntegerError, "decimals can not be converted"

    result = ""
    for numeral, integer in romanNumeralMap:
        while n >= integer:
            result += numeral
            n -= integer
    return result

#Define pattern to detect valid Roman numerals
romanNumeralPattern = re.compile("""
    ^                   # beginning of string
    M{0,4}              # thousands - 0 to 4 M's
    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                        #            or 500-800 (D, followed by 0 to 3 C's)
    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                        #        or 50-80 (L, followed by 0 to 3 X's)
    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                        #        or 5-8 (V, followed by 0 to 3 I's)
    $                   # end of string
    """ ,re.VERBOSE)

def fromRoman(s):
    """convert Roman numeral to integer"""
    if not s:
        raise InvalidRomanNumeralError, 'Input can not be blank'
    if not romanNumeralPattern.search(s):
        raise InvalidRomanNumeralError, 'Invalid Roman numeral: %s' % s

    result = 0
    index = 0
    for numeral, integer in romanNumeralMap:
        while s[index:index+len(numeral)] == numeral:
            result += integer
            index += len(numeral)
    return result
Подякували: koala, A.N.Onim2

4

Re: Алгорит зміни числа с римського в арабський

Що означають "-=" та "+="?

5

Re: Алгорит зміни числа с римського в арабський

var = var + 1

Скорочення

var += 1
Подякували: A.N.Onim1

6

Re: Алгорит зміни числа с римського в арабський

koala, чи можна про

koala написав:

в циклі знаходимо найбільше число, яке нам підходить (вигляду {1,4,5,9}*10^n), додаємо до результату це число в римській нотації і віднімаємо його від аргументу.

детальніше?

7

Re: Алгорит зміни числа с римського в арабський

Що робиться тут:

romanNumeralPattern = re.compile("""
    ^                   # beginning of string
    M{0,4}              # thousands - 0 to 4 M's
    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                        #            or 500-800 (D, followed by 0 to 3 C's)
    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                        #        or 50-80 (L, followed by 0 to 3 X's)
    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                        #        or 5-8 (V, followed by 0 to 3 I's)
    $                   # end of string
    """ ,re.VERBOSE)

?
З модулем re трішки знайомий, але все ж не розумію.

8

Re: Алгорит зміни числа с римського в арабський

Ну а що тут розуміти, в коментарях все розписано. Це ж просто регулярка, краще покажіть що йде далі

9

Re: Алгорит зміни числа с римського в арабський

Тобто "покажіть, що йде далі"?

10

Re: Алгорит зміни числа с римського в арабський

A.N.Onim написав:

Тобто "покажіть, що йде далі"?

Ну просто я підозрював що цю регулярку ви знайшли в якомусь скрипті, і я мав на увазі той скрипт. Але я так розумію що я помилявся

11

Re: Алгорит зміни числа с римського в арабський

eukreign, а можна назву модулю? Щоб можна було імпортувати:

import xxxxxx

Чи цього модулю немає в стандартній бібліотеці Пітону?