- •Ю.Е. Алексеев, а.В. Куров
- •Часть 4
- •Алексеев Юрий Евтихович Куров Андрей Владимирович
- •8. Символьный тип данных
- •8.1 Общие сведения и библиотечные функции
- •8.2 Примеры программ обработки символьных данных
- •8.3 Задания на обработку символьных матриц
- •9. Строки
- •9.1 Общие сведения и библиотечные функции
- •9.2 Примеры программ обработки строк (массивова символов)
- •9.3 Задания на обработку строк
- •10. Типы данных структура и объединение
- •10.1 Общие сведения о структурах
- •10.2 Примеры программ обработки структур
- •10.3 Задания на обработку структур
- •10.4 Объединения
- •10.5 Примеры программ обработки объединений
- •11. Файлы
- •11.1 Основные сведения о файлах
- •11.2 Библиотечные функции для работы с файлами
- •11.3 Примеры программ обработки текстовых файлов
- •11.4 Задания на обработку текстовых файлов.
- •11.5 Примеры программ обработки бинарных файлов
- •11.6 Задания на бинарные файлы.
- •12. Тип данных указатель
- •12.1 Общие сведения Объявления и присваивания
- •Операции с указателями
- •Приоритеты операций при работе с указателями.
- •Взаимосвязь массивов и указателей
- •12.2 Динамические переменные и массивы Динамические переменные
- •Динамические массивы
- •Двумерные динамические массивы
- •Доступ к элементам динамической матрицы
- •Библиотечные функции с для работы с динамическими переменными и массивами
- •Передача в функции динамических массивов
- •13 Динамические структуры данных
- •13.1 Списки Линейный список
- •Пример программы работы с однонаправленным списком
- •Пример программы работы с двунаправленным списком
- •13.2 Задания на обработку списков.
- •13.3 Деревья бинарные
- •Структура бинарного дерева
- •Примеры работ с бинарным деревом
- •Список литературы
- •Алфавитный указатель
- •Вопросы для самопроверки Символы
- •Структуры
- •Указатели
9.2 Примеры программ обработки строк (массивова символов)
Пример 1. Составить программу нахождения в тексте на русском языке слова, содержащего максимальное количество букв 'а', 'ы' и 'и',
Решение этой задачи можно разбить на три этапа.
На первом этапе выполнить ввод слов (в конце слов допускаются знаки препинания) текста в элементы массива, состоящего из массивов символов (массива слов), и изменение кодов символов введённых слов на принятые для символьных констант.
На втором этапе найти в массиве слов индекс слова, удовлетворяющего условию задачи, а также количество символов в слове.
На третьем этапе, если нужных слов в тексте нет, то следует вывести соответствующее сообщение, иначе - вывести найденное слово, предварительно удалив в его конце знак препинания, если таковой есть, и перекодировав символв слова для правильного вывода.
Текст программы имеет следующий вид.
#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "D:\\temp\\RusString.h"
int _tmain(int argc, _TCHAR* argv[])
{
char
s[100][20],//массив ля ввода слов
smax[20], //для слова с максимальным количеством гласных букв
cc
;
int
ns,//количество введённых в s слов
nmax,//искомое максимальным количеством букв А и Я
imax,//место этого слова в массиве s
lmax,//длина этого слова
i,j,k
;
/* строка для отладки
искомое, максимальным: количеством гласных букв.
*/
//Этап 1
//ввод слов в массивы s[i],i=0,1,2,.. и подсчёт их количества ns
OutPuts("Введите текст");
for(i=0;;i++)
{
scanf("%s%c",s[i],&cc);
// printf("%s%d\n",s[i],cc);//для отладки
RusIn(s[i],s[i]);//перекодировка для сравнения с константами
if(cc==10)
{
ns=i;
// printf("ns=%d\n",ns+1);//для отладки
break;
}
}
//Этап 2
//поиск слова с максимальным количеством букв а ы и
ns++;
nmax=0;
for(i=0;i<ns;i++)
{
k=0;
for(j=0;s[i][j]!=0;j++)
{
switch(s[i][j])
{
case 'а':case 'ы':case 'и':
k++;
break;
}
}//for(j=0;s[i][j]!=0;j++)
if(k>nmax)
{
nmax=k;
imax=i;
lmax=j;
}
}//for(i=0;i<ns;i++)
//Этап 3
if(nmax==0)
//правильный вывод строковой константы с русскими буквами
OutPuts("Нет слов с буквами а ы и");
else
{
if(s[imax][lmax-1]>32)
s[imax][lmax-1]=0;//удалить хнак препинания
//Подготовить строку в s[imax] для вывода и вывести
OutPuts("Найденное слово:");
OutPuts(s[imax]);
}
return 0;
}
Протокол ввода-вывода:
Введите текст
искомое, максимальным: количеством гласных букв.
Найденное слово: максимальным
Для продолжения нажмите любую клавишу . . .
Пример 2. Во введенной строке символов, включающей и буквы русского алфавита, найти все слова, начинающиеся с заглавных букв. Найденные слова вывести в алфавитном порядке.
Решение этой задачи можно разбить на три этапа. Во-первых надо выделить из строки все слова. Под словом будем понимать произволную последовательность символов, не содержащую символов-разделителей. К символам - разделителям будем относить следующие символы: пробел, запятую, точку, вопросительный знак, восклицательный знак, двоеточие, точку с запятой, тире. Следует заметить, что каждый пользователь может сам сформировать этот списоки в соответствии со своими запросами. Решение задачи выделения слов легко можно решить, используя функцию strtok. Испольование этой функции позволяет последовательно находить указатель на начало очередного слова в исходной строке и отмечать нуль - символом его конец. Найденные указатели будем сохранять в массиве sl (массиве всех слов) и подсчитывать их количество.
На втором этапе из найденного массива всех слов выберем только требуемые слова и сформируем из них второй массив указателей zag (массив требуемых слов).
На третьем этапе произведем сортировку указателей во втором массиве по возрастанию слов с использованием подготовленной функции sort.
Текст программы имеет следующий вид.
#include "stdafx.h"
#include "conio.h"
#include "string.h"
#include "D:\\temp\\RusString.h"
void sort(char *zag[], int n);
int _tmain(int argc, _TCHAR* argv[])
{
const int nn=250;
char s[nn], //исходная строка символов
*sl[nn/2],//массив указаиелей на слова строки
*c, //указатель на очередное слово
*zag[nn/2], //массив указателей на слова, начинающиеся с заглавных
//букв
ch;
int m,i,n,o;
/* текст для отладки
Подключите RusString.h. Он содержит функции RusIn, GetsIn, RusOut, OutPuts для работ с русскими буквами.
*/
OutPuts("Подготовьте текст и нажмите Enter:\n");
gets(s);
OutPuts("\nКонтрольный вывод:\n");
puts(s);
RusIn(s,s);//перекодирование введённого текста
c=strtok(s," ,.?!:;"); // поиск первого слова
m=0;
while(c!=NULL) //цикл поиска последующих слов
{
sl[m]=c; //занесение указателя на очередное слово в массив
//указателей на слова
m++;
c=strtok(NULL," ,.?!:;"); //поиск очередного слова
}
if(m==0)
//не найдено ни одного слова
OutPuts("Во введённом тексте нет слов\n");
else
{
//вывод найденных слов
OutPuts ("\nСписок найденных слов:");
for(i=0;i<m;i++)
OutPuts(sl[i]);// printf("%s\n",sl[i]);
//поиск слов начинающихся на заглавные буквы
n=0;
o=0;
for(i=0;i<m;i++)
if (sl[i][0]>='A'&&sl[i][0]<='Z'
|| sl[i][0]>='А'&&sl[i][0]<='Я')
{ //Найдено слово, начинающееся с большой буквы
//Вкючение этого слова в массив zag требуемых слов
zag[n]=sl[i];
n++;
}
if(n>0)
{
//Вывод слов, начинающихся с большой буквы
OutPuts("\nСписок слов, начинающихся с большой буквы:");
for(i=0;i<n;i++)
OutPuts(zag[i]);
//упорядочение слов в массиве zag слов и вывол
sort(zag,n);
OutPuts("\nСписок слов после упорядочения:");
for(i=0;i<n;i++)
OutPuts(zag[i]);//printf("%s\n",zag[i]);
}
else
OutPuts("\nСписок слов, начинающихся с большой буквы:");
}
getch();
return 0;
}
void sort(char *zag[], int n)
{ //функция сортировки массива слов методом пузырька
int i,k;
char *c;
bool flag;
k=0;
do
{
flag=false;
k++;
for (i=0;i<n-k;i++)
if (strcmp(zag[i],zag[i+1])>0)
{
c=zag[i];
zag[i]=zag[i+1];
zag[i+1]=c;
flag=true;
}
}while(flag);
}
Протокол ввода-вывода:
Подготовьте текст и нажмите Enter:
Подключите RusString.h. Он содержит функции RusIn, GetsIn, RusOut, OutPuts для р
абот с русскими буквами.
Контрольный вывод:
Подключите RusString.h. Он содержит функции RusIn, GetsIn, RusOut, OutPuts для р
абот с русскими буквами.
Список найденных слов:
Подключите
RusString
h
Он
содержит
функции
RusIn
GetsIn
RusOut
OutPuts
для
работ
с
русскими
буквами
Список слов, начинающихся с большой буквы:
Подключите
RusString
Он
RusIn
GetsIn
RusOut
OutPuts
Список слов после упорядочения:
GetsIn
OutPuts
RusIn
RusOut
RusString
Он
Подключите
Пример 3. Найти в строке символов все слова, в которых количество цифр составляет не менее заданного значения.
При решении этой задачи также, как и в предыдущем примере, сначала строится массив всех слов sl, содержащихся в исходной строке. Затем с помощью функции zifra определяется, содержит ли слово требуемое количество цифровых символов. Слова, удовлетворяющие поставленному условию, переписываются во второй массив zif (массив требуемых слов).
Выполнять перекодирование введённых русских букв не нужно, так как сравнений с константами не потребуется, но для вывода поясняющих текстов - констант на русском языке потребуется использовать функцию OutPuts.
//Найти в втроке все слова, в которых количество цифр не менее заданного
#include "stdafx.h"
#include "string.h"
#include "conio.h"
#include "D:\\temp\\RusString.h"
bool zifra(char *s,int k)
{//подпрограмма анализа количества цифр в слове
int n;
n=0; //текущее количество цифровых символов
for (int j=0; j<strlen(s) && n<k; j++)
{
if (s[j]>='0'&&s[j]<='9') //анализ очередного символа на цифру
n++;
}
if (n>=k)
return true;
else
return false;
}
int _tmain(int argc, _TCHAR* argv[])
{const int nn=250;//максимальная длина строки символов
char
s[nn], //исходная строка символов
*sl[nn/2], //массив указателей на слова строки
*c, //указатель на текущее слово
*zif[nn/2]//массив указатель на слова, удовлетворяющие условию
;
int m,i,n,k;
/* текст для отладки
ФЫВ1И,Й66. , 333 .,4У4У4УQ:?AS5;ZXC6V6V6V6V6:
*/
//Ввод исходных данных
OutPuts("Подготовьте текст и нажмите Enter:");
gets(s);
OutPuts("\nКонтрольный вывод:");
puts(s);
OutPuts("\nВведите количество цифр: ",0);
scanf("%d",&k);
//Выделение слов
c=strtok(s," ,.?!;:");
m=0;
while (c!=NULL)
{
sl[m]=c;
m++;
c=strtok(NULL," ,.?!;:");
}
//Вывод результата по выделению слов
if (m==0)
OutPuts("\nВ строке нет слов:\n");
else
{
//вывод найденных слов
OutPuts ("\nСписок найденных слов:");
for (i=0;i<m;i++)
printf("%s\n",sl[i]);
//поиск слов с количеством цифр, большим заданного k
n=0;
for (i=0;i<m;i++) //цикл по всем выделенным словам
if (zifra(sl[i],k))
{
zif[n]=sl[i];//занесение слова, удовлетворяющего условию, в
//результирующий массив
n++;
}
if (n>0)
{
//вывод слов с количеством цифр, большим заданного k
OutPuts ("\nСписок слов с количеством цифр, большим заданного ",0);
printf("k=%d:\n",k);
for(i=0;i<n;i++)
printf("%s\n",zif[i]);
}
else
printf("%s k=%d %s\n",RusOut(s,"\nСлов с количеством цифр, большим заданного "),k,RusOut(&s[50]," НЕТ!\n"));
}
getch();
return 0;
}
Протокол ввода-вывода:
Подготовьте текст и нажмите Enter:
ФЫВ1И,Й66. , 333 .,4У4У4УQ:?AS5;ZXC6V6V6V6V6:
Контрольный вывод:
ФЫВ1И,Й66. , 333 .,4У4У4УQ:?AS5;ZXC6V6V6V6V6:
Введите количество цифр: 2
Список найденных слов:
ФЫВ1И
Й66
333
4У4У4УQ
AS5
ZXC6V6V6V6V6
Список слов с количеством цифр, большим заданного k=2:
Й66
333
4У4У4УQ
ZXC6V6V6V6V6
Пример 4. Подсчитаь в строке количество симметричных слов из нескольких букв и вывести результат.
Для решения поставленной задачи надо выделять слова и проверять очередное слово на симметричность. Проверка на симметричность выполняется путем сравнения символов, находящихся на одинаковом расстоянии от центра симметрии слова. Если очередную пару сравниваемых символов образуют одинаковые символы, то процесс сравнения продолжается. Если очередную пару образуют разные символы, то продолжать проверку нет смысла, в этом случае выполняется выход из цикла и формируется признак несимметричности.
При проверке слова на симметричность можно отказаться от перекодирования вводимых данных для русских букв, так как они не будут ставниваться с соответствующими символами - константами. А если потребовать, чтобы и все выводимые поясняющие тексты были на русском языке и не нуждались в перекодировании для правильного вывода, то проще всего воспрользоваться альтернативным кодированием, используя заголовочный файл locale.h и оператор setlocale( LC_CTYPE, ".1251" );. Однако в этом случае при наличии русских букв для контрольного вывода строки всё же придётся отказаться от контрольного вывода вводимых данных в готовой прграмме. А вот при отладке, когда потребуется наблюдать текущие значения введенных символов, их потребуется перекодировать. В представленной ниже программе операторы, которые требуется удалить после завершения отладки, помечены комментариями //для отладки
// Подсчёт количества симметричных слов
#include "stdafx.h"
#include "conio.h"
#include "string.h"
#include <locale.h>
#include "D:\temp\RusString.h"//Для отладки
int _tmain(int argc, _TCHAR* argv[])
{ const int nn=250;
chars[nn], //исходная строка символов
*c, //указатель на очередное слово
*sim[nn/2]; //массив указателей на слова,являющиеся симметричными
int i,l,m,n;
bool flag; //признак симметричности слова
setlocale( LC_CTYPE, ".1251" );
printf("Введите строку\n");
gets(s);
printf("\nnКонтрольный вывод:\n"); //Для отладки
RusIn(s,s); //Для отладки
puts(s);//Для отладки
/* Для отладки
AA,,я "АННА" ОНО казак, шалаш?
*/
c=strtok(s," ,.?!:;"); // поиск первого слова
n=0;
while(c!=NULL) //цикл поиска последующих слов
{
m=strlen(c);
RusIn(c,c);//Для отладки
for(i=0;i<m/2;i++)
if(c[i]!=c[m-1-i])
break;
if(m>1 && i==m/2)
n++;
c=strtok(NULL," ,.?!:;"); //поиск очередного слова
}
if (n==0)
printf("\nСимметричных слов нет");
else
printf("\nКоличество симметроичных слов равно %d\n",n);
getch();
return 0;
}
Протокол ввода-вывода:
Введите строку
AA,,я "АННА" ОНО казак, шалаш?
Количество симметроичных слов равно 5
Пример 5. Найти в строке, содержащей буквы только латинского алфавита, максимальное слово и подсчитать, сколько раз в нем встретился каждый символ этого слова.
Для решения этой задачи необходимо выделить все слова, содержащиеся в строке. При выделении очередного слова следует сравнить его с максимальным словом и, если оно превышает максимальное, скопировать текущее слово в максимальное.
Для определения количества раз, которое встретился каждый символ в слове, необходимо каждый символ слова сравнить с каждым из последующих символов этого слова. Для этого надо записать вложенный цикл Во внешнем цикле перебираются все символы слова, а во внутреннем перебираются все последующие символы слова и сравниваются с текущим символом. При их совпадении счетчик увеличивается на единицу. Начальное значение счетчика устанавливается равным единице, т.к. наличие очередного символа означает, что один раз этот символ уже встретился.
При нахождении совпадающего символа его надо удалить из строки, чтобы в дальнейшем этот символ не мог рассматриваться в качестве нового символа. Для этого следует в еще одном вложенном (третьем) цикле произвести сдвиг всех последующих символов на одну позицию в сторону еачала слова. В этом случае количество анализируемых символов (длина строки) уменьшается на единицу. При этом также надо на единицу уменьшить текущее значение параметра цикла, т.к. после сдвига символов строки влево в текущей позиции оказывается еще не анализировавшийся символ.
// Нахождение максимального слова в строке,
//содержащей только латинские буквы, и подсчёт,
//сколько раз в нем встретился каждый символ этого слова
#include "stdafx.h"
#include "conio.h"
#include "string.h"
#include <locale.h>
int _tmain(int argc, _TCHAR* argv[])
{ char s[100], //исходная строка символов
max[100]; //максимальное слово
char *c; //указатель на очередное слово
int i,j,n,k ;
/* Строка для отладки
prst ppppppprrrrttt trsptrsrppp
*/
setlocale( LC_CTYPE, ".1251" );
printf("Введите строку:\n");
gets(s);
printf("Исходная строка -%s",s);
//задание начального значения для максимального слова –
//пустое слово
strcpy(max,"");
c=strtok(s," ,.?!:;");
while (c!=NULL) //цикл выделения слов и поиска максимального
{
if (strcmp(c,max)>0)
strcpy(max,c);
c=strtok(NULL," ,.?!:;");
}
n=strlen(max);
printf("\nМаксимальное слово - %s",max);
printf("\nбукваколичество");
for (i=0;i<n;i++)//цикл анализа каждого символа слова
{
k=1;
//цикл сравнения очередного символа со всеми
//последующими символами слова
for (j=i+1;j<n;j++)
if (max[i]==max[j])
{
k++;
//удаление символа-копии (перепись всех последующих
//символов со сдвигом влево на однк позицию
for (int l=j;l<n;l++)
max[l]=max[l+1];
n--;
j--;
}
printf("\n %c-%d",max[i],k);
}
getch();
return 0;
}
Протокол ввода-вывода:
Введите строку:
prst ppppppprrrrttt trsptrsrppp
Исходная строка -prst ppppppprrrrttt trsptrsrppp
Максимальное слово - trsptrsrppp
букваколичество
t-2
r-3
s-2
p-4
