Препроцессор, оформление программы и средства ввода/вывода
Проверка корректности строки выделена в функцию testString, которая последовательно рассматривает каждый символ строки и проверяет, принадлежит ли он английскому алфавиту и/или русскому и/или является цифрой и/или разделителем. В начале допускаются в качестве разделителей только пробелы, поэтому используется дополнительная переменная start. Исходно она равна нулю, и только после появления в строке символа алфавита и/или цифры она становится равна единице. Пока start равна нулю, допускается только пробел в качестве разделителя:
if ( (*str) == ' ' ) { goodSymb = 1; }
а когда start равна единице, допускается любой разделитель (точка, запятая, пробел):
if ( (isDelimeter(*str)) && start ) { goodSymb = 1; }
Кодирование строки выполнено в один проход. В данной задаче сложность алгоритма определяется количеством проходов по строке, поэтому их желательно минимизировать. Разделители остаются без изменения. Когда встречается слово, оно кодируется в функции change231, в которую передается вся строка и позиция начала слова. После кодирования слова функция change231 возвращает позицию конца слова (номер следующего за концом слова символа).
Сама перестановка символов выполнена последовательно попарно. Требуемый результат - 231 получается, если сначала переставить первый символ со вторым (получив 213) и далее второй с третьим (получив как раз 231). Такой подход оказывается справедлив и в случае, когда остается два символа (12 - 21), т.е. алгоритм перестановки сводится к работе лишь с двумя рядом стоящими символами (перемене их мест). Однако требуется перестановка только в рамках тройки символов, поэтому на каждом третьем шаге следует пропустить одну позицию:
if (((i-startPos)%3 == 0) && (!isDelimeter(str[i]))) i++;
Алгоритм основной программы уже был определен ранее.
- Ввести входную строку.
- Если строка пустая, то закончить работу.
- Преобразовать входную строку.
- Вывести преобразованную строку.
- Ввести очередную входную строку и вернуться к действию (2).
Соответственно будет выглядеть и реализация.
- Ввести входную строку:
printf("Введите строку для кодирования\n"); readString(str);
- Если строка пустая, то закончить работу:
while(*str != '\0') { . . . } printf("Работа закончена"); return 0;
- Преобразовать входную строку:
if (testString(str) == 0) { printf("Ошибка во входной строке\n"); } else { processString(str); printf("%s\n", str); }
- Вывести преобразованную строку:
processString(str); printf("%s\n", str);
- Ввести очередную входную строку и вернуться к действию (2):
while(*str != '\0') { ... printf("Введите строку для кодирования\n"); readString(str); }
Вопросы и задачи для самостоятельного решения
- Как можно задать числовую константу в Си?
- Сколько необходимо создать файлов, чтобы реализовать модуль в Си?
- Зачем нужны заголовочные файлы в Си?
- В каких случаях возможно переполнение буфера при вводе строки? Какими способами можно этого избежать?
- Напишите программу перевода десятичного числа в шестнадцатеричное. Входное число должно считываться из стандартного потока ввода (клавиатура). Перевод должен работать для чисел длиной не менее 100 цифр.
- Напишите программу кодирования слова методом перестановки символов 3-1-2. Входное слово должно считываться из стандартного потока ввода (клавиатура). Кодирование должно работать для слов длиной не менее 300.