Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6-8 по АЯ и ОП.doc
Скачиваний:
1
Добавлен:
06.11.2018
Размер:
576.51 Кб
Скачать

Тема №6. Строковый тип данных (string).

Задание. Введите с клавиатуры предложение в переменную типа строка символов (string), выделите из предложения отдельные слова в массив слов, проведите преобразование предложения и слов в соответствии с индивидуальным заданием, распечатайте результат обработки на экране монитора. Длина вводимого предложения не более 80 символов. При выполнении задания необходимо во всех случаях, где это можно, использовать процедуры и функции для работы со строками. Все задания подразумевают необходимость применения не менее трех разных библиотечных процедур или функций. Программа не должна содержать глобальных переменных. Каждая из процедур и функций должна получать исходные данные в виде параметров, результат также должен быть параметром или возвращаться функцией.

Пример выполнения задания

Примерное задание: во введенном с клавиатуры предложении, расположите слова в обратной последовательности, не меняя расположение разделительных знаков.

Для решения поставленной задачи используем методику проектирование программы «сверху-вниз». Начнем с основной части программы. Определим ее функциональную спецификацию, перечислив набор тех подпрограмм, которые она будет выполнять. Программа будет содержать:

  1. Подпрограмму (функцию или процедуру) для ввода предложения.

  2. Подпрограмму разбиения предложения на массив слов и массив разделительных знаков между словами. Каждый из массивов будет представлять собой массив строк.

  3. Подпрограмму преобразования слов (если есть по заданию).

  4. Подпрограмму сборки предложения из массива слов и массива разделительных знаков.

  5. Подпрограмму распечатки исходного предложения и результата.

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

// Подпрограмма ввода предложения

function Input : string;

begin Input := 'Верите ли вы, что задача решена?'; end;

// Подпрограмма выделения слов из предложения в массив слов

procedure Select ( S : string; R : string; var M : array of string; var n : shortint );

begin end;

// Подпрограмма сборки результирующего предложения

function Sborka ( Slova, Znaki : array of string; Ns,Nr : shortint ) : string;

begin Sborka := ''; end;

// Подпрограмма распечатки результата

procedure PrintResult ( Predl, Res : string );

begin end;

// Основная часть программы

const N = 20; // Максимальное количество букв в каждом слове предложения

var

Predl, // Исходное предложение

Razd, // Строка разделительных знаков

Alph, // Строка букв алфавита

Res : // Результат работы программы

string;

Slova : array [1..N] of string; // Массив слов в предложении

Znaki : array [1..N] of string; // Массив строк разделительных знаков между словами

Ns, Nr : shortint; // Количество слов и количество строк разделительных знаков

begin

// Исходные данные

Predl := Input;

Razd := ' ,./;!?';

Alph := 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'+

'йцукенгшщзхъфывапролджэячсмитьбю';

// Выделение массивов слов и строк разделительных знаков

Select ( Predl, Razd, Slova, Ns );

Select ( Predl, Alph, Znaki, Nr );

// Сборка результирующего предложения

Res := Sborka ( Slova, Znaki, Ns, Nr );

// Распечатка результата

PrintResult ( Predl, Res );

Readln;

end.

Простые подпрограммы предлагается рассмотреть самостоятельно по приведенному ниже полному тексту программы. Для подробного рассмотрения составляют интерес только самые сложные части.

Наиболее сложной будет подпрограмма выделения (Select) из исходного предложения массива слов или массива строк разделительных знаков (алгоритм для них один и тот же). Она будет принимать в качестве исходных данных предложение и строку из разделительных знаков. Результат работы подпрограммы – массив слов и массив строк разделительных знаков между ними, а также количество элементов в каждом из этих массивов.

Для разбиения исходного предложения на массив слов можно предложить множество алгоритмов. Один из вариантов приведен здесь (попутно заметим, что все действия будут проводиться над копией исходного предложения):

  1. Установить счетчик слов равным -1, то есть пока не выделено ни одного слова.

  2. Если строка содержит символы, то перейти на пункт 3, иначе завершить работу подпрограммы.

  3. Увеличить счетчик слов.

  4. Выделить слово из предложения подпрограммой выделения одного слова (SelectWord) и записать его в массив слов. После выделения слова оно будет удалено из предложения.

  5. Повторить алгоритм, начиная с пункта 2.

В данном алгоритме не определена подпрограмма выделения одного слова (SelectWord). Для начала ее можно сделать фиктивной, как это делалось со всеми подпрограммами основной части программы, и реализовать алгоритм подпрограммы Select. Но, логичнее, завершить проект программы, разработав алгоритм подпрограммы выделения одного слова, который может быть следующим:

    1. Удалить разделительные знаки в начале строки.

    2. Найти индекс первого разделительного знака.

    3. Копировать слово из предложения от начала строки до разделительного знака (сам знак не копируется).

Каждое из указанных действий будет реализовано по своему алгоритму. Так функция удаления разделительных знаков принимает в качестве параметров строку исходного предложения и строку разделительных знаков и делает два действия:

  1. Заполняет множество символами-разделителями (в примере программы ниже по тексту это действие выполняется отдельной функцией).

  2. До тех пор, пока первый символ строки входит во множество символов-разделителей и строка не пустая, удаляет первый символ.

Функция поиска первого разделительного знака в предложении принимает в качестве параметров строку исходного предложения и строку разделительных знаков и реализует следующий алгоритм:

  1. Вначале считаем, что индекс первого разделительного знака не найден, то есть значение индекса, записанное в переменной n, равно 0.

  2. Для всех символов строки разделительных знаков выполняем пункты, начиная с 3-го.

  3. Ищем номер позиции разделительного знака в строке предложения.

  4. Если знак найден (его позиция не равна 0), то, если n=0 или номер найденной позиции меньше, чем значение переменной n, то сохраняем в ней новое значение.

Функция копирования слова из исходного предложения до позиции разделительного знака (CopyWord) принимает в качестве параметров исходное предложение и номер позиции разделительного знака. Если номер позиции не равен 0, то копируется часть предложения от 1-го символа, до знака (сам знак не копируется). В противном случае копируется весь остаток предложения. Следующим действием удаляется скопированная часть исходного предложения.

По данному проекту выполнена следующая программа:

type

TCharSet = set of char;

// Подпрограмма ввода предложения

function Input : string;

var s : string;

begin

writeln ( 'Введите предложение' );

readln ( s );

Input := s;

end;

// Заполняет множество символами строки

function FillCharSet ( s : string ) : TCharSet;

var i : byte; Rset : TCharSet;

begin

Rset := [];

for i := 1 to length(s) do Rset := Rset + [s[i]];

FillCharSet := Rset;

end;

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

procedure DelRazd ( var S : string; R : string );

var i : byte; Rset : TCharSet;

begin

// Заполнить множество символов-разделителей

Rset := FillCharSet(R);

// Удалить разделительные знаки в начале строки

while (S<>'')and(S[1] in Rset) do Delete(S,1,1);

end;

// Ищет первый разделительный знак

function FindIndex ( S, R : string ) : byte;

var i,k,n : byte;

begin

n := 0;

for i := 1 to length(R) do

begin

k := Pos(R[i],S);

if k > 0 then

begin

if (n = 0) or (k < n)

then n := k;

end;

end;

FindIndex := n;

end;

// Копировать слово

function CopyWord ( var S : string; n : byte ) : string;

var Sl : string;

begin

if n > 0

then Sl := Copy(S,1,n-1)

else Sl := S;

// Удалить слово

if n > 0

then Delete(S,1,n)

else S := '';

CopyWord := Sl;

end;

//Выделяет слово до первого разделительного знака

function SelectWord( var S : string; R : string ) : string;

var i,n : byte; Rset : TCharSet;

begin

// Удалить разделительные знаки в начале строки

DelRazd(S,R);

// Найти индекс первого разделительного знака

n := FindIndex(S,R);

// Копировать слово

SelectWord := CopyWord(S,n);

end;

// Выделяет все слова из предложения в массив

procedure Select(S : string; R : string;

var M : array of string; var n : shortint);

begin

n := -1;

while S <> '' do

begin

inc(n);

M[n] := SelectWord(S,R);

end;

end;

function Sborka(Slova, Znaki : array of string;

Ns,Nr : shortint) : string;

var Rez : string; s,z : shortint;

begin

Rez := '';

s := Ns; z := -1;

while ( s >= 0 ) or ( z <= Nr ) do

begin

if s >= 0 then

begin

Rez := Rez + Slova[s];

dec(s);

end;

if z <= Nr then

begin

inc(z);

Rez := Rez + Znaki[z];

end;

end;

Sborka := Rez;

end;

procedure PrintResult( Predl, Res : string);

begin

writeln('Исходное предложение - '#13, Predl);

writeln('Результат - '#13, Res);

end;

const N = 20;

var

Predl, Razd, Alph, Res : string;

Slova : array [1..N] of string;

Znaki : array [1..N] of string;

Ns, Nr : shortint;

begin

// Исходные данные

Predl := Input;

Razd := ' ,./;!?';

Alph := 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'+

'йцукенгшщзхъфывапролджэячсмитьбю';

// Выделение массивов слов и разделительных знаков

Select ( Predl, Razd, Slova, Ns );

Select ( Predl, Alph, Znaki, Nr );

// Сборка результирующего предложения

Res := Sborka ( Slova, Znaki, Ns, Nr );

// Распечатка результата

PrintResult ( Predl, Res );

Readln;

end.