Руководство полного чайника по программированию на языке Си

       

написать функцию инвертирования порядка символов


/* Задача: написать функцию инвертирования порядка символов в массиве char. A B C D ---> D C B A В решении можно использовать рекурсию. */

/* Мы приведем рекурсивное и нерекурсивное решения (два варианта) */ #include

/* Сначала - несколько служебных функций. */

/* ФУНКЦИЯ ПОДСЧЕТА ДЛИНЫ СТРОКИ. Как уже объяснялось, строка текста - это массив char, в конце которого помещен символ '\0'. Сам символ \0 не считается. */ int strlen(char s[]){ /* функция от массива букв */ int counter = 0; /* счетчик и одновременно индекс */

while(s[counter] != '\0') /* пока не встретился признак конца текста */ counter++; /* посчитать символ */ return counter; /* сколько символов, отличных от '\0' */ }

/* ФУНКЦИЯ ПЕЧАТИ СТРОКИ. Печатаем каждый элемент массива как символ при помощи putchar(c). Как только встречаем элемент массива, равный '\0' - останавливаемся. Заметьте, что при наличии завершающего символа нам НЕ НАДО передавать в функцию размер массива, он нам неинтересен.

В конце эта функция переводит строку. */ int putstr(char s[]){ int i = 0; /* индекс */

while(s[i] != '\0'){ putchar(s[i]); i++; } putchar('\n'); return i; }

/* ТЕПЕРЬ МЫ ЗАНИМАЕМСЯ ФУНКЦИЕЙ ИНВЕРТИРОВАНИЯ. Для этого нам нужна вспомогательная функция: сдвиг элементов массива на 1 влево.

Исходный массив: A B C D E F <---------- Результат: B C D E F F - Последний элемент удваивается.

n - размер массива. Функция работает так:

Исходный массив: A B C D E F n=6 После i=1 B B C D E F После i=2 B C C D E F После i=3 B C D D E F После i=4 B C D E E F После i=5 B C D E F F i=6 ==> остановка.

*/ void shiftLeft(char s[], int n){ int i;



for(i=1; i < n; i++) s[i-1] = s[i]; }

/* Функция инвертирования. Идея такова: - если длина массива меньше или равна 1, то инвертировать нечего, ибо массив состоит из 1 или 0 элементов. - если длина массива > 1, то a) Спасти нулевой элемент массива. A B C D E F | | V tmp

b) Сдвинуть массив влево B C D E F F

c) В последний элемент массива поместить спасенный нулевой элемент. tmp | V B C D E F A


d) Инвертировать начало массива длиной n-1. {B C D E F}A
Получится: F E D C B A
Что и требовалось.
s[] - массив, n - его длина. */ void reverse(char s[], int n){ char tmp;
if(n <= 1) /* нечего инвертировать */ return;
tmp = s[0]; /* спасти */ shiftLeft(s, n); /* сдвинуть */ s[n-1] = tmp; /* переместить */
reverse(s, n-1); /* инвертировать начало */ }
/* ВТОРАЯ ВЕРСИЯ нерекурсивна. Рекурсия заменена циклом. Длина начала массива, которую надо инвертировать, вынесена на переменную length. */ void reverse1(char s[], int n){ char tmp; int length;
for(length=n; length > 1; --length){ tmp = s[0]; shiftLeft(s, length); s[length-1] = tmp; } }
char testString[] = "abcdefghijklmnopqrstuvwxyz";
/* Если не задать размер массива, он будет вычислен компилятором автоматически. Он будет равен числу букв внутри "..." ПЛЮС одна ячейка для невидимого символа '\0' на конце. В данном случае это 27. */
void main(){ int len;
len = strlen(testString); /* вычислить длину строки: 26 ('\0' на конце не считается) */
printf("Строка для теста: \"%s\", ее длина %d\n", testString, len); /* Обратите внимание на два момента: - строку (массив char) следует печатать по формату %s - чтобы внутри "..." напечатать символ " надо изобразить его как \"
А чтобы в putchar напечатать символ ' надо писать putchar('\''); */
/* Первая инверсия */ reverse(testString, len); putstr("Инвертированная строка:"); putstr(testString);
/* Вторая инверсия - возвращает в исходное состояние */ reverse1(testString, len); putstr("Инвертированная в исходное состояние строка:"); putstr(testString); }

Содержание раздела