Вот проблема кодирования для тех, кто любит такие вещи. Давайте посмотрим, как вы реализуете (конечно, на выбранном вами языке) функцию, которая возвращает читаемое человеком представление String указанного целого числа. Например:
- humanReadable (1) возвращает «один».
- humanReadable (53) возвращает «пятьдесят три».
- humanReadable (723603) возвращает «семьсот двадцать три тысячи шестьсот три».
- humanReadable (1456376562) возвращает «один миллиард четыреста пятьдесят шесть миллионов триста семьдесят шесть тысяч пятьсот шестьдесят два».
Бонусные баллы за особенно умные / элегантные решения!
Это может показаться бессмысленным упражнением, но существует множество реальных приложений для такого рода алгоритма (хотя поддержка чисел до миллиарда может быть излишней :-)
Уже был вопрос по этому поводу: конвертировать целые числа в записанные числа
Ответ для C #, но я думаю, что вы можете понять это.
Поддерживает до 999 миллионов, но без отрицательных чисел:
String humanReadable(int inputNumber) {
if (inputNumber == -1) {
return "";
}
int remainder;
int quotient;
quotient = inputNumber / 1000000;
remainder = inputNumber % 1000000;
if (quotient > 0) {
return humanReadable(quotient) + " million, " + humanReadable(remainder);
}
quotient = inputNumber / 1000;
remainder = inputNumber % 1000;
if (quotient > 0) {
return humanReadable(quotient) + " thousand, " + humanReadable(remainder);
}
quotient = inputNumber / 100;
remainder = inputNumber % 100;
if (quotient > 0) {
return humanReadable(quotient) + " hundred, " + humanReadable(remainder);
}
quotient = inputNumber / 10;
remainder = inputNumber % 10;
if (remainder == 0) {
//hackish way to flag the algorithm to not output something like "twenty zero"
remainder = -1;
}
if (quotient == 1) {
switch(inputNumber) {
case 10:
return "ten";
case 11:
return "eleven";
case 12:
return "twelve";
case 13:
return "thirteen";
case 14:
return "fourteen";
case 15:
return "fifteen";
case 16:
return "sixteen";
case 17:
return "seventeen";
case 18:
return "eighteen";
case 19:
return "nineteen";
}
}
switch(quotient) {
case 2:
return "twenty " + humanReadable(remainder);
case 3:
return "thirty " + humanReadable(remainder);
case 4:
return "forty " + humanReadable(remainder);
case 5:
return "fifty " + humanReadable(remainder);
case 6:
return "sixty " + humanReadable(remainder);
case 7:
return "seventy " + humanReadable(remainder);
case 8:
return "eighty " + humanReadable(remainder);
case 9:
return "ninety " + humanReadable(remainder);
}
switch(inputNumber) {
case 0:
return "zero";
case 1:
return "one";
case 2:
return "two";
case 3:
return "three";
case 4:
return "four";
case 5:
return "five";
case 6:
return "six";
case 7:
return "seven";
case 8:
return "eight";
case 9:
return "nine";
}
}
import math
def encodeOnesDigit(num):
return ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'][num]
def encodeTensDigit(num):
return ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'][num-2]
def encodeTeens(num):
if num < 10:
return encodeOnesDigit(num)
else:
return ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'][num-10]
def encodeTriplet(num):
if num == 0: return ''
str = ''
if num >= 100:
str = encodeOnesDigit(num / 100) + ' hundred'
tens = num % 100
if tens >= 20:
if str != '': str += ' '
str += encodeTensDigit(tens / 10)
if tens % 10 > 0:
str += '-' + encodeOnesDigit(tens % 10)
elif tens != 0:
if str != '': str += ' '
str += encodeTeens(tens)
return str
def zipNumbers(numList):
if len(numList) == 1:
return numList[0]
strList = ['', ' thousand', ' million', ' billion'] # Add more as needed
strList = strList[:len(numList)]
strList.reverse()
joinedList = zip(numList, strList)
joinedList = [item for item in joinedList if item[0] != '']
return ', '.join(''.join(item) for item in joinedList)
def humanReadable(num):
if num == 0: return 'zero'
negative = False
if num < 0:
num *= -1
negative = True
numString = str(num)
tripletCount = int(math.ceil(len(numString) / 3.0))
numString = numString.zfill(tripletCount * 3)
tripletList = [int(numString[i*3:i*3+3]) for i in range(tripletCount)]
readableList = [encodeTriplet(num) for num in tripletList]
readableStr = zipNumbers(readableList)
return 'negative ' + readableStr if negative else readableStr
using System;
namespace HumanReadable
{
public static class HumanReadableExt
{
private static readonly string[] _digits = {
"", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
"eighteen", "nineteen"
};
private static readonly string[] _teens = {
"", "", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"
};
private static readonly string[] _illions = {
"", "thousand", "million", "billion", "trillion"
};
private static string Seg(int number)
{
var work = string.Empty;
if (number >= 100)
work += _digits[number / 100] + " hundred ";
if ((number % 100) < 20)
work += _digits[number % 100];
else
work += _teens[(number % 100) / 10] + "-" + _digits[number % 10];
return work;
}
public static string HumanReadable(this int number)
{
if (number == 0)
return "zero";
var work = string.Empty;
var parts = new string[_illions.Length];
for (var ind = 0; ind < parts.Length; ind++)
parts[ind] = Seg((int) (number % Math.Pow(1000, ind + 1) / Math.Pow(1000, ind)));
for (var ind = 0; ind < parts.Length; ind++)
if (!string.IsNullOrEmpty(parts[ind]))
work = parts[ind] + " " + _illions[ind] + ", " + work;
work = work.TrimEnd(',', ' ');
var lastSpace = work.LastIndexOf(' ');
if (lastSpace >= 0)
work = work.Substring(0, lastSpace) + " and" + work.Substring(lastSpace);
return work;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(1.HumanReadable());
Console.WriteLine(53.HumanReadable());
Console.WriteLine(723603.HumanReadable());
Console.WriteLine(1456376562.HumanReadable());
Console.ReadLine();
}
}
}
Существует одна огромная проблема в реализации этой функции. Это будущая локализация. Эта функция, написанная носителем английского языка, скорее всего, не будет работать правильно для любого другого языка, кроме английского. Почти невозможно написать общую легкую локализуемую функцию для любого диалекта человеческого языка в мире, если вам действительно не нужно, чтобы она была общей. На самом деле в реальном мире вам не нужно работать с огромными целыми числами, поэтому вы можете просто хранить все числа в большом (или даже не очень) массиве строк.
согласился, что есть ряд реальных приложений. в качестве такового уже существует ряд реализаций реального мира.
это было частью bsdgames, так как почти навсегда ...
> man number
12,254
из12254
вас может сделать12254.to_s.reverse.split('').each_slice(3).to_a.map{|x|x=x.join().reverse}.reverse.join(',')