Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторный практикум

.pdf
Скачиваний:
48
Добавлен:
15.06.2021
Размер:
3 Mб
Скачать

Инициализация массива строк. Инициализация массивов строк выполняется аналогично инициализации элементов одномерного массива:

char mas_words[3][10]={”one”,”two”,”three”,”four”};

Ввод строки с клавиатуры. Для ввода строки с клавиатуры используется функция cin.get(строковая_переменная, масимальный_размер_строки);

Не рекомендуется использовать для ввода оператор cin, так как если строка содержит пробелы, то будет введена только часть строки до первого пробела.

Вывод строки на экран. При выводе строки можно использовать оператор cout и функцию puts.

puts(строковая_переменная); cout<<строковая_переменная;

Функции обработки строк. В интегрированной среде программирования Visual Studio 2015 имеется набор библиотечных функций обработки строк. Некоторые функции приведены в приложении 2. Для использования библиотечных функций необходимо применить директиву препроцессору #include <cstring>;

Способы выделения слова из строки символов. При программи-

ровании задач с использованием строкового типа данных часто необходимо выделить слово (слова). Это можно реализовать с помощью формирования слова:

1) путем анализа каждого символа исходной строки;

2)с помощью функции strtok;

3)с помощью функции strpbrk. Рассмотрим эти способы.

Формирование слова путем анализа каждого символа исходной

строки. Объявим переменную строкового типа, в которую будем заносить символы исходной строки, пока не встретится символ «пробел» или признак окончания строки '\0'. Перед формированием слов пропустим начальные пробельные символы.

Текст программы:

#include <iostream> using namespace std; int main()

143

{

char str[60];// исходная строка

char word[60];

// слово

//cin << str;

 

cin.get(str,256);

// ввод строки

int k = 0; int j = 0; int i = 0;

if (str[0] == ' ') // если в начале исходной //строки есть пробелы

{

//пока встречается пробел, считаем количество //пробелов

while (str[k++] == ' '); k--;

}

//цикл от первого непробельного символа до

//конца строки

for (i = k; i<strlen(str); i++)

{

/* если текущий символ не пробел и не признак конца строки, то запишем его в переменную word*/

if (str[i] != ' ' && str[i] != '\0') word[j++] = str[i];

//встретили пробел или признак окончания строки else

{

if (j != 0)// слово было сформировано?

{

//записать последним символом признак окончания //строки

word[j] = '\0'; puts(word);//вывод слова на экран j = 0;// обнулить значение j для

//формирования нового слова

}

}

}

}

Данная программа будет работать корректно, если после ввода с клавиатуры всех символов строки будет введен пробел. Если пробел не ввести, то последнее слово не выведется на экран. Подумайте почему?

144

Результат выполнения программы представлен на рис.1:

Рис.1. Результат выполнения программы по формированию массива слов

Формирование слова с помощью функции strtok. Функция strtok позволяет выделять из строки слова, разделенные символамиразделителями, при этом она портит содержимое исходной строки.

Приведем фрагмент программы выделения слова из строки символов с использованием данной функции:

char

*word = new char[80];

// слово

char

str[80];

//

исходная строка

cin.get(str,256);

//

ввод строки

/*выделить слово из строки. Символом-разделителем является символ из набора символов , . ? */

word = strtok(str, " ,.?");

while (word) // пока word не пусто

{

puts(word); // вывод на экран слова word = strtok(NULL, " ,.?");// переход к

//следующему слову

}

При вводе строки в этом случае не надо добавлять пробел. Функция корректно выделит слова. Результат выполнения программы с использованием функции strtok приведен на рис.2.

145

Рис.2. Результат выполнения программы с использованием функции strtok

Формирование слова с помощью функции strpbrk. Функция strpbrk находит в анализируемой строке str первое местоположение любого из заданных символов-разделителей. При этом содержимое исходной строки не изменяется.

Фрагмент программы с использованием данной функции:

char *word = new char[80];// слово

char *str = new char[80];// исходная строка cin.get(str, 256); // ввод строки

char* w; //указатель на первый символ- //неразделитель

int n;// размер слова

w = strpbrk(str, " ,.?");// нахождение первого

//символа-неразделителя while (w != NULL)//пока в строке есть символы-

//разделители

{

n = w - str;// вычисление размера слова // формирование слова путем копирования //n символов

strncpy(word, str, n);

word[n++] = '\0';//установить признак // конца строки

puts(word); // вывести слово на экран str += n;// перейти к следующему слову w = strpbrk(str, " ,.?");// продолжить

// поиск разделителя в строке

}

// формирование последнего слова

if (strlen(str) != 0)strcpy(word, str); puts(word); //вывод последнего слова на экран

146

Результат выполнения программы, соответствующей данному фрагменту, представлен на рис.3.

Рис.3. Результат выполнения программы с использованием функции strpbrk

Примеры программирования

Пример 1. Дана строка символов. Вывести на экран четыре самых коротких слова исходной строки.

Решение. Сформируем массив из слов исходной строки, отсортируем его по длине слов и выведем на экран первые четыре элемента отсортированного массива. При сортировке массива слов воспользуемся алгоритмом сортировки (см. лабораторную работу № 4).

Текст программы:

#include <iostream> using namespace std; int main()

{

char str[80];// str - исходная строка cout << "input string >"; cin.get(str,256);

char word[10][20];// word - массив слов

int k = 0; // k - количество слов в строке str /*Формирование массива слов word из строки str*/

for (int i = 0; i<strlen(str); i++)//Пока не

// строки конец

{

while (str[i] == ' ')i++;// Пропуск пробелов int j=0;// Количество символов в слове

// word[k]

/* Пока текущий символ не пробел и не нуль-символ*/ while (str[i] != ' ' && str[i] != '\0')

147

// Формирование k-го слова в массиве word word[k][j++] = str[i++];

word[k++][j] = '\0';//Нуль-символ в

//конец слова

}

/*Сортировка слов в порядке увеличения их длины*/ char* sh_word = new char[20]; // sh_word –

//короткое слово из неотсортированных for (int i = 0; i<k; i++)//Цикл по всем словам

//массива word

{

// Пусть i-е слово будет самым коротким strcpy(sh_word, word[i]);

int num = i;//Номер короткого слова в //массиве

/* Поиск короткого слова среди неотсортированных в массиве слов */

for (int j = i; j<k; j++)

/* Если длина текущего слова меньше, чем длина короткого слова */

if (strlen(word[j]) < strlen ( sh_word

))

{

/*Короткое слово - это текущее слово */ strcpy(sh_word, word[j]);

num = j; /*Номер короткого

слова в массиве*/

}

strcpy(word[num], word[i]);/* Обмен местами i-го слова и короткого слова */

strcpy(word[i], sh_word);

}

delete[] sh_word;/* Освобождение динамической памяти */

// Вывод на экран четырех коротких слов

for (int i = 0; i<4; i++) cout << word[i] << " " << endl;

}

148

Результат выполнения программы приведен на рис.4.

Рис.4. Результат выполнения программы к примеру 1

Пример 2. Дана строка символов, разделенных пробелами, точками и запятыми. Сформировать новую строку, содержащую слова исходной строки, поставив перед самыми короткими словами в строке символ * (звездочка).

Текст программы:

#include <iostream> using namespace std; int main()

{

char* str = new char[80];/*исходная строка*/ char* word = new char[20];/* слово в строке*/ char* newstr = new char[80];/*новая строка*/ cout << "Input string >";

cin.get(str,256); // Ввод строки

/* Пусть длина самого короткого слова = длине строки*/

int minlen =

strlen(str);

/* stroka = str + 'пробел'*/

char* stroka =

new char[strlen(str) + 2];

strcpy(stroka,

str);

strcat(stroka,

" ");

word = strtok(str, " ,.?");

while (word)//

word - первое слово в строке

{

 

/* Если длина короткого слова меньше длины текущего слова, то длина короткого слова = длине текущего слова */

if (minlen>strlen(word)) minlen =

strlen(word);

 

word = strtok(NULL, " ,.?");

/* Следую-

щее слово*/

 

}

 

/* Выделение динамической памяти

*/

 

149

word = new char[20];

/* Формирование новой строки */

int n;

 

 

newstr[0] = '\0';

// newstr - пустая строка

str[0] = '\0';

// str - пустая строка

// word указывает на символ-разделитель в stroka

word = strpbrk(stroka, " ,.?");

while (word != NULL)

// Цикл по всем словам

{

 

 

n = word - stroka;// n - длина слова strncpy(str, stroka, n);/* str - текущее

слово*/

str[n++] = '\0';

/* Если длина текущего слова равна длине самого короткого слова, то в newstr заносим символ '*' */

if (strlen(str) == minlen) strcat(newstr,

"*");

strcat(newstr, str);/* В newstr записывается текущее слово*/

strcat(newstr, " ");/* В newstr записывается

пробел*/

stroka += n;/*переход к следующей части

строки*/

// Поиск символа-разделителя в stroka word = strpbrk(stroka, " ,.?");

}

cout << "Out string >";

puts(newstr);// Вывод новой строки на экран

}

По я сн е н ия к пр о гр ам м е . В первой части программы осуществляется поиск длины самого короткого слова. Далее формируется новая строка путем копирования слов из исходной строки. Если длина выделенного слова исходной строки равна длине минимального слова, то сначала будет записан символ *, а затем скопировано слово исходной строки.

Результат выполнения данной программы представлен на рис.5.

150

Рис.5. Результат выполнения программы к примеру 2

Пример 3. Дана строка, в которой имеются символы *. Подсчитать количество подстрок, заключенных между символами *. Определить самую длинную подстроку.

Текст программы:

#include <iostream> using namespace std; int main()

{

char* str = new char[80];/* str - исходная строка*/ cout << "Input string >";

cin.get(str,256);

// Ввод строки

int

count = 0,

// Количество подстрок

 

maxlen = 0,// Длина наибольшей подстроки

 

pos = 0,// Номер текущей позиции в str

 

j = 0;// Счетчик символов в подстроке

char* substr = new char[80];/* substr - текущая

подстрока*/

 

char

maxstr[80];

/* maxstr - наибольшая подстро-

ка */

 

 

maxstr[0] = '\0';

// maxstr - пустая строка

for (int i = 0; i<strlen(str); i++)/* Цикл - по всей исходной строке */

if (str[i] == '*')/* Если текущий символ =

'*' */

{

/* Формирование подстроки */ substr[j] = '\0';

count++;/* Увеличение количества под-

строк на 1 */

if (count>1)/* Если это не первый сим-

вол '*' */

{

if (maxlen <= i - pos)

151

/* Если длина наибольшей подстроки меньше или равна длине текущей подстроки, то длина наибольшей подстроки = длине текущей подстроки, а наибольшая подстрока = текущей подстроке */

{

maxlen = i - pos; strcpy(maxstr, substr);

}

}

substr[0] = '\0';/* substr - пустая

строка */

pos = i + 1;/* Переход к следующей части исходной строки */

j = 0;/* Установка начальных значений

*/

}

/* Если текущий символ не '*', то переписываются текущие символы из исходной строки в подстроку */

else substr[j++] = str[i]; // Вывод результатов

cout << "cout substr >" << --count << endl; cout << "max substring >" << maxstr <<

"len=" << maxlen << endl;

}

По я сн е н ия к пр о гр а м м е . Зададим начальное значение самой длинной подстроки, равное 0. В первой части программы формируется подстрока, заключенная между *, и вычисляется длина подстроки. Если длина подстроки оказывается больше, чем ранее определенная, то теперь эта подстрока будет максимальной. После просмотра всех возможных подстрок определяется истинное значение максимальной подстроки.

Результат выполнения программы приведен на рис.6.

Рис.6. Резудьтат выполнения программы к примеру 3

152