Найти тему
ИнформатиК

Числа - в текст.

Здравствуйте.

Припомнил тут одну задачку времен своей школьной олимпиады. Нужно было преобразовать введенное число от 1 до 999 в текст, но не просто числа в символы, а в "название" этого числа, например 431 должно выдать на выходе текст "четыреста тридцать один".

К моему удивлению, поиски в интернете результата не дали, найти разбор такой интересной задачи мне не удалось.

А задачка вполне себе жизненная, например, для синтезаторов речи, где может быть использован и текст, и звукозапись.

Как мы вообще проговариваем числа? Разбиваем справа на группы по 3 разряда. Первая группа (числа меньше тысячи) названия не имеет, мы просто говорим "двести двадцать пять". Можно условно назвать это "единицами", но мы обычно не говорим "тридцать семь единиц", а просто "тридцать семь". Дальше идут тысячи, потом миллионы, миллиарды и т. д. Поэтому, научившись озвучивать одно-, двух-, и трехзначные числа, мы сможем произнести или напечатать "название" любого числа, например, число 25615377 мы сначала разделим на группы по 3 разряда 25 615 377 и "расшифруем" каждую группу, добавив к ней соответствующее название: "двадцать пять миллионов шестьсот пятнадцать тысяч триста семьдесят семь".

А как мы формируем название внутри трёхзначной группы? Да очень просто: называем сотни, десятки и единицы. Конечно, можно ввести 999 названий всех чисел и напрямую индексироваться к ним, но напомню, что задача была олимпиадная, соответственно, с ограничением по времени. Да и решение это слишком прямолинейное, а мы хотим всё сделать красиво.

Начнем? Объявляем массивы-константы, в которые заносим названия сотен, десятков и единиц.

const

sot: array[0..9] of string = ('','Сто ','Двести ','Триста ','Четыреста ','Пятьсот ', 'Шестьсот ','Семьсот ','Восемьсот ','Девятьсот ');

dec: array[0..9] of string = ('','Десять ','Двадцать ','Тридцать ','Сорок ', 'Пятьдесят ', 'Шестьдесят ','Семьдесят ','Восемьдесят ','Девяносто ');

ed: array[0..9] of string = ('','Один','Два','Три','Четыре','Пять', 'Шесть','Семь','Восемь','Девять');

Обратите внимание, что индексация начинается с нуля, а первые элементы этих массивов равны '' (пустая трока). Это сделано для того, чтобы не проверять нули в соответствующих разрядах , а сразу индексироваться по значению разряда. Если в разряде будет ноль - он будет пропущен (программа выведет пустую строку, т. е. ничего не выведет).

Кроме этого, после названий сотен и десятков ставим пробелы, чтобы при выводе отделить их друг от друга и от единиц.

Необходимо также вспомнить, что числа от 11 до 19 имеют свои "оригинальные" названия. Их также помещаем в массив. Индексы массива для простоты соответствуют названиям чисел.

ed11_19: array[11..19] of string = ('Одиннадцать','Двенадцать',

'Тринадцать','Четырнадцать','Пятнадцать','Шестнадцать',

'Семнадцать','Восемнадцать','Девятнадцать');

Все названия собраны. Объявляем переменные

var

n, k: integer;

Здесь n - введенное число, k - промежуточная переменная.

Всё, начинаем. Вводим исходные значения, проверяя их на корректность. Договоримся также, что будет реализован бесконечный цикл (чтобы программа запускалась один раз для ввода нескольких значений), а для выхода нужно ввести ноль

BEGIN

repeat

repeat

write('Введите число от 1 до 999 (0 - выход): ');

readln(n);

until (n>=0) and (n<1000);

Сразу выводим сотни

write(sot[n div 100]);

Сохраняем в промежуточной переменной k остаток от деления на 100, т. е. десятки и единицы и продолжаем работу.

k:=n mod 100;

Почему просто не поменять значение n? Дело в том, что если ввести целые сотни (100, 200, 300 и т. д.), то после этой операции n станет равным нулю и программа завершится, а мы этого не просили. Поэтому введена промежуточная переменная k, а значение n мы не трогаем.

Итак, осталось число k - дву- или однозначное. Проверяем его на "оригинальность". Если это так - выводим название из массива ed11_19, а если нет - то просто выводим десятки и единицы

if (k>10) and (k<20) then writeln(ed11_19[k])

else writeln(dec[k div 10], ed[k mod 10])

И завершаем программу, если введен ноль

until n=0

END.

Результаты проверки работы:

Введите число от 1 до 999 (0 - выход): 6

Шесть

Введите число от 1 до 999 (0 - выход): 25

Двадцать Пять

Введите число от 1 до 999 (0 - выход): 341

Триста Сорок Один

Введите число от 1 до 999 (0 - выход): 500

Пятьсот

Введите число от 1 до 999 (0 - выход): 994

Девятьсот Девяносто Четыре

Введите число от 1 до 999 (0 - выход): -25

Введите число от 1 до 999 (0 - выход): 207

Двести Семь

Введите число от 1 до 999 (0 - выход): 1040

Введите число от 1 до 999 (0 - выход): 714

Семьсот Четырнадцать

Введите число от 1 до 999 (0 - выход): 803

Восемьсот Три

Введите число от 1 до 999 (0 - выход): 68

Шестьдесят Восемь

Введите число от 1 до 999 (0 - выход): 0

Как видим, всё работает. Некорректные числа пропускаются без обработки, при вводе нуля программа завершается. По-моему, это лайк!