Преобразовать натуральное число в последовательность символов.
Решение 1. В двух предыдущих задачах мы научились разбивать число на цифры и преобразовывать цифры в символы. Теперь надо совместить эти действия. Поскольку цифры отделяются с конца числа, очередную цифру надо приписывать в начало уже построенной последовательности. Для этого можно использовать операцию конкатенации (соединения) строк. Такая операция, как правило, присутствует в системах программирования, которые допускают использование строк как самостоятельного типа данных. Вот как выглядит функция преобразования в системе КуМир:
алг лит int2str (apг цел n)
дано n>0 | преобразуем только натуральнее числа
надо | знач содержит строковую запись числа n
нач цел nn:
nn: =n | КуМир не разрешает изменять
| аргумент, поэтому создаем копию
знач:=""
нц пока nn>0
знач:= digit2char(mod(пп,10)) + знач
nn:= div(nn,10)
кц
кон
Решение 2, К сожалению, операция конкатенации есть не во всех системах. В Си, например, нет типа данных, аналогичного лит в КуМире или string в Турбо Паскале, нет и конкатенации. Правда, в стандартной библиотеке Си есть функция strcat, но она позволяет выполнять только правое присоединение (вызов strcat;(a,b) в КуМире соответствует присваиванию а: ==а+b), а нам нужно левое.
Получается противоречие: цифры числа поступают на обработку справа налево, а записывать их мы можем только слева направо. Значит, сначала надо где-то сохранить все цифры, а потом преобразовать их в символы и объединить в строку. Такая отложенная обработка легко реализуется с помощью рекурсии.
char * int2str (int n, char *s)
/* Функция преобразует целое п в строку символов, записывает в строку s и возвращает
в качестве результата. */
{
char dig[2];
/* строка для хранения очередной цифры */
if (n==0) strcpy(s,"");
else
int2sfcr (n/10, s);
{/* рекурсивный вызов;
в s записывается число n без последней цифры */
dig[0] == digit2char(n%10);
dig[l] == '\0'; /* концевой ноль */
strcat(s,dig);
}
return s;
}
Логику рекурсивного вызова можно в данном случае объяснить так: чтобы записать число, надо записать это число без последней цифры, а потом добавить последнюю цифру.
Упражнение 2. Доработайте функцию int2str, чтобы она могла преобразовывать в строку отрицательные числа и ноль. Обратите особое внимание на преобразование нуля: не допускайте появления ведущего нуля при обработке положительных чисел. Сделайте два варианта преобразования: с использованием конкатенации и рекурсии.
От волшебного числа 10 к недесятичным системам счисления
Разбивая число на цифры, мы постоянно выполняли деление на 10; Это вполне естественно -- ведь мы анализировали запись числа в десятичной системе счисления. Но давайте вспомним одну из заповедей хорошего стиля программирования: в программе не должно быть волшебных чисел, их надо заменять именованными константами. Следуя этому правилу, надо включить в программу описание константы (или ввести специальную переменную, если в языке нет понятия константы) base со значением 10 (имя base означает основание, имеется в виду основание системы счисления) и заменить число 10 на base.
Оказывается, такая замена не просто улучшает вид программы, она имеет еще и глубокий содержательный смысл. Давайте подумаем, что будет, если указать для base вместо 10 какое-нибудь другое значение? Прежде чем читать дальше, попробуйте сами ответить на этот вопрос.
Последовательно деля число на 10, мы тем самым выделяем в нем единицы, десятки, сотни и т.д., то есть формируем запись этого числа в десятичной системе счисления. Подставив вместо 10 другое значение base, мы получим запись в другой системе счисления, основанием которой будет выбранное значение base.
При base<10 наша функция будет правильно преобразовывать число в запись в соответствующей системе счисления. При base>10 необходимо внести коррективы в функцию digit2char, чтобы обрабатывать цифры (именно цифры!), большие 9. Обычно в качестве таких цифр используют латинские буквы: цифра А соответствует 10, В — 11 и т.д. В шестнадцатеричной системе, где традиционно используется такая запись, самой старшей цифрой оказывается F — 15, В принципе этот ряд можно продолжить до конца латинского алфавита. Значением цифры Z будет 35, что дает возможность использовать все системы счисления вплоть до Зб-ичной.
Упражнение 3. Доработайте функцию digit2str так, чтобы она обрабатывала цифры от 0 до 35. Цифрам от 0 до 9 должны ставиться в соответствие символы десятичных цифр, а цифрам от 10 до 35 — заглавные латинские буквы. Можно считать, что используется кодировка ASCII, то есть все символы заглавных латинских букв расположены в кодовой таблице подряд.
Упражнение 4. Переделайте функцию char2str так, чтобы она могла записывать число в любой системе счисления с основаниями от 2 до 36. Желательную систему счисления можно указывать в качестве дополнительного параметра.
|