Здравствуйте.
Припомнил тут одну задачку времен своей школьной олимпиады. Нужно было преобразовать введенное число от 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
Как видим, всё работает. Некорректные числа пропускаются без обработки, при вводе нуля программа завершается. По-моему, это лайк!