Cпособ преобразовать числовые слова в целые числа Python
Задача заключается в преобразование числовых слов в целые числа и наоборот без использования дополнительных библиотек, чистый код.
Пример:
"минус триста одиннадцать целых две десятых" -> -311,2
567.012 -> "пятьсот шестьдесят семь целых двенадцать сотых"
и т.д.
Ответы (2 шт):
Тут вообще-то принято приводить код с хотя бы минимальной попыткой решения. Тем не менее подтолкну в верном направлении: используйте табличные алгоритмы. Для ясности приведу самую простенькую программку, которая преобразует в текст целое положительное число в диапазоне от 0 до 9999 (для простоты, число вводится в виде строки).
# -*- coding: cp1251 -*-
table = (
("один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять"),
(None, "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"),
("сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"),
("одна тысяча", "две тысячи", "три тысячи", "четыре тысячи", "пять тысяч", "шесть тысяч", "семь тысяч", "восемь тысяч", "девять тысяч")
)
table2 = ("десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать")
num = input("Введите целое положительное число: ")
text = ""
order = 0
error = 0
for c in reversed(num):
if c==' ': continue
if c=='0':
order+= 1
c1 = c
continue
if c>'0' and c <='9':
if order > 3:
print("Ошибка: число слишком большое!")
error = 1
break
word = table[order][ord(c)-0x31]
if word:
text = word + " " + text
else:
text = table2[ord(c1)-0x30]
order+= 1
c1 = c
continue
print("Ошибка: посторонние символы в целом положительном числе!")
error = 1
break
if text=="": text = "нуль"
if not error:
print("Введённое число: %s" %text)
Для чисел со знаком и точкой - пожалуйста, доработайте самостоятельно.
Обратная задача так же основана на таблицах. Вернее - словарях. Разбиваете входной текст на токены, такие как, например, "тысяча", "одна тысяча", "девять", "целых", "целая", и т.д., и с помощью словаря подставляете их значения (например, в виде пары (число, порядок)) и конструируете число (каким образом, придумайте сами).
В общем, идея, надеюсь, ясна? Ваяйте код))
UPD. Обновил пример кода - исправил случай с числами от 10 до 19.
Слишком общий вопрос, хватит лениться, попробуй хоть что-нибудь сам сделать
Как преобразовать число, описанное словами в число, описанное цифрами?
Вот тут это можно посмотреть: https://trinket.io/python3/3ecffa94e9
Первым делом разбиваем нашу строку на токены:
tokens = input().split(" ")
Проверяем, является ли минус первым токеном:
minus = False
if tokens[0] == "минус":
tokens = tokens[1:]
minus = True
Разделим целую и дробную часть:
integerPart = tokens
floatPart = None
if "целых" in tokens:
integerPart = tokens[:tokens.index("целых")]
floatPart = tokens[tokens.index("целых")+1:-1]
floatPartType = tokens[-1]
Любой токен можно представить в виде модификатора. Так например токен тысяч значит тысяч того, что было до него. Простые же числа просто добавляются к результату
Определим токены и то, как они влияют на число:
def add(count): return lambda x: x+count
def mul(count): return lambda x: x*count
start_tokens = [
[["один", "одна"], add(1)],
[["два"], add(2)],
[["три"], add(3)],
[["четыре"], add(4)],
[["пять"], add(5)],
[["шесть"], add(6)],
[["семь"], add(7)],
[["восемь"], add(8)],
[["девять"], add(9)],
[["десять"], add(10)],
[["десятков", "десяток", "десятка"], mul(10)],
[["одиннадцать"], add(11)],
[["двенадцать"], add(12)],
[["тринадцать"], add(13)],
[["четырнадцать"], add(14)],
[["пятнадцать"], add(15)],
[["шестнадцать"], add(16)],
[["семнадцать"], add(17)],
[["восемнадцать"], add(18)],
[["девятнадцать"], add(19)],
[["двадцать"], add(20)],
[["тридцать"], add(30)],
[["сорок"], add(40)],
[["пятьдесят"], add(50)],
[["шестьдесят"], add(60)],
[["семьдесят"], add(70)],
[["восемьдесят"], add(80)],
[["девяносто"], add(90)],
[["сто"], add(100)],
[["сотен", "сотни"], mul(100)],
[["двести"], add(200)],
[["тысяч", "тысячи"], mul(1000)],
]
Теперь надо реализовать метод для сопоставления значения:
def matchToken(token):
for tokens in start_tokens:
if token in tokens[0]:
return tokens[1]
Объявляем финальный результат:
value = 0
floatValue = 0 # Вещественная часть
Проходимся по каждому токену целочисленной части:
for token in integerPart:
value = matchToken(token)(value)
Аналогично по вещественной (если она имеется), и добавляем её в результат:
floatTypeTokens = {
"десятых": 10,
"сотых": 100,
"тысячных": 1000
}
if floatPart != None:
floatValue = 0
for token in floatPart:
floatValue = matchToken(token)(floatValue)
value += floatValue / floatTypeTokens[floatPartType]
Добавляем минус при необходимости:
value *= -1 if minus else 1
Если вы хотите что бы пять шесть выдавали ошибку, то вам стоит проверять, заменяются ли в числе ТОЛЬКО нули. Если вам интересно напишите, я опишу алгоритм (код точно давать не буду)
Полный код:
def add(count): return lambda x: x+count
def mul(count): return lambda x: x*count
startTokens = [
[["один", "одна"], add(1)],
[["два"], add(2)],
[["три"], add(3)],
[["четыре"], add(4)],
[["пять"], add(5)],
[["шесть"], add(6)],
[["семь"], add(7)],
[["восемь"], add(8)],
[["девять"], add(9)],
[["десять"], add(10)],
[["десятков", "десяток", "десятка"], mul(10)],
[["одиннадцать"], add(11)],
[["двенадцать"], add(12)],
[["тринадцать"], add(13)],
[["четырнадцать"], add(14)],
[["пятнадцать"], add(15)],
[["шестнадцать"], add(16)],
[["семнадцать"], add(17)],
[["восемнадцать"], add(18)],
[["девятнадцать"], add(19)],
[["двадцать"], add(20)],
[["тридцать"], add(30)],
[["сорок"], add(40)],
[["пятьдесят"], add(50)],
[["шестьдесят"], add(60)],
[["семьдесят"], add(70)],
[["восемьдесят"], add(80)],
[["девяносто"], add(90)],
[["сто"], add(100)],
[["сотен", "сотни"], mul(100)],
[["двести"], add(200)],
[["триста"], add(300)],
[["четыреста"], add(400)],
[["тысяч", "тысячи"], mul(1000)],
]
floatTypeTokens = {
"десятых": 10,
"сотых": 100,
"тысячных": 1000
}
def matchToken(token):
for tokens in startTokens:
if token in tokens[0]:
return tokens[1]
while True:
try:
tokens = input().split(" ")
value = 0
minus = False
if tokens[0] == "минус":
tokens = tokens[1:]
minus = True
integerPart = tokens
floatPart = None
if "целых" in tokens:
integerPart = tokens[:tokens.index("целых")]
floatPart = tokens[tokens.index("целых")+1:-1]
floatPartType = tokens[-1]
for token in integerPart:
value = matchToken(token)(value)
if floatPart != None:
floatValue = 0
for token in floatPart:
floatValue = matchToken(token)(floatValue)
value += floatValue / floatTypeTokens[floatPartType]
value *= -1 if minus else 1
print(value)
except:
print("Error")
Как преобразовать число, описанное цифрами в число, описанное словами?
Интересный вопрос. На самом деле точного решения нет, ведь одно и то же число можно описать по-разному.