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

AlgStr / Библиотека / Разные источники / СД - Строки (метод ук-ия)

.pdf
Скачиваний:
37
Добавлен:
23.03.2015
Размер:
371.93 Кб
Скачать

Выход из цикла while (k<=n) and (S[k]<>i) do происходит, если закончились символы строки или найден символ, совпадающий с символом i. По умолчанию компилятор языка Pascal проверяет первое условие и если оно истинно, то только тогда проверятся второе. Если неизвестен порядок проверки условий, то необходимо обезопасить решение от выхода за границу строки (k уже больше n, но проверяется S[k]<>i). Тогда можно использовать логическую пе-

ременную flag.

program S_3_2;

var n, k, i: integer; s: string;

flag: boolean; {признак отсутствия буквы в строке} begin

writeln (Введите строку’); readln (S);

n := length(S);

for i := ’a’ to ’z’ do begin

k := 1; flag := true; while (k<=n) and flag do

if S[k] = i then flag := false

else

k := k+1;

if not flag then write(i,’ ’)

end; writeln

end.

13

Пример 4. Даны строки S, S1 и символ C. Вставить в строку S перед

каждым символом C строку S1.

Решение оформлено в виде процедуры S41( S, S1, C ).

Входные параметры: строки S, S1, C.

Выходные параметры: строка S.

procedure S41(var S, S1: string; C: char); var i, j, k, n: integer;

begin

k:= ord(S1[0]); n:= ord(S[0]); i := 1;

while i <= n do{повторять, пока не закончилась строка S} begin

if S[i]=C then begin

{сдвиг вправо элементов от очередного символа C

до конца строки S} for j:=n downto i do

S[j+k] := S[j]; n := n+k;

S[0] := chr(n); {увеличить длину строки}

{вставить на освободившееся место символы строки S1} for j:= 1 to k do

S[i+j-1] := S1[j]; i := i+k

end;

i := i+1 end

end;

14

3 ИСПОЛЬЗОВАНИЕ СТАНДАРТНЫХ ПРОЦЕДУР И ФУНКЦИЙ

Пример 5. Дана строка. Напечатать в алфавитном порядке все различные латинские прописные буквы этой строки.

Для решения задачи используется не посимвольная обработка строки S, как в примере 3, а стандартная функция pos (см. Приложение).

program S_5_1;

var k, i: integer; S: string;

begin

writeln (Введите строку’); readln (S);

for i := ’A’ to ’Z’ do begin

k := pos(i,S); if k > 0 then

write(i,’ ’)

end; writeln

end.

Пример 6. Даны строки S, S1, S2. Заменить в строке S все вхождения под-

строки S1 подстрокой S2.

Решение оформлено в виде процедуры S61( S, S1, S2).

Входные параметры: строки S, S1, S2.

Выходные параметры: строка S.

15

procedure S61(var S, S1, S2: string); var n, k: integer;

begin

n := length (S1);

k := pos (S1, S); {k – позиция первого вхождения S1 в S} while k <> 0 do {повторять, пока S1 входит в S}

begin

{удалить в строке S с k-ой позиции n символов} delete (S, k, n);

{вставить строку S2 в строку S с k-ой позиции} insert (S2, S, k);

k := pos (S1, S) end

end;

Способ решения, реализованный в процедуре S61, предполагает, что заме-

няемая строка S1 не содержится в строке S2. В противном случае получим либо зацикливание, либо просто неверное решение.

Способ решения, реализованный в процедуре S62, корректно решает по-

ставленную задачу при любых исходных данных. Результат формируется в новой строке Sr.

Входные параметры: строки S, S1, S2.

Выходные параметры: строка Sr.

procedure S62(var S, S1, S2, Sr: string);

var n, k: integer;

begin

n := length (S1); Sr:=’’;

k := pos (S1, S); {k – позиция первого вхождения S1 в S}

16

while k <> 0 do {повторять, пока S1 входит в S} begin

{добавить в Sr все символы S до первого вхождения S1}

Sr := Sr+copy(S,1,k-1);

{удалить из S первое вхождение S1 и все символы до него} delete (S, 1, k+n-1);

Sr := Sr+S2; {добавить S2 в строку Sr вместо S1} k := pos (S1, S)

end;

Sr := Sr+S {добавить в строку Sr остаток строки S} end;

Пример 7. Даны строки S, S1 и символ C. Вставить в строку S перед каждым символом C строку S1.

Эта задача может быть решена с использованием посимвольной обработки строки S, как в процедуре S41( S, S1, C ) примера 4.

Другой вариант решения задачи использует стандартные процедуры и функции обработки строк (см. Приложение) и оформлен в виде процедуры

S71( S, S1, Sr, C ). Результат формируется в новой строке Sr.

Входные параметры: строки S, S1, C.

Выходные параметры: строка Sr.

procedure S71(var S, S1, Sr: string; C: char);

var k: integer;

begin

Sr:=’’;

k := pos (C, S); {k - позиция первого вхождения C в S}

17

while k <> 0 do {повторять, пока C входит в S} begin

{добавить в строку Sr все символы до первого вхождения C}

Sr := Sr+copy(S,1,k-1);

{удалить из S все символы до первого вхождения C и C} delete (S, 1, k);

{вставить в строку Sr строку S1 и символ C}

Sr := Sr+S1+C; k := pos (C, S)

end;

Sr := Sr+S; {добавить в строку Sr остаток строки S} end;

Упражнения

1) Проверьте корректность выполнения кода фрагмента программы для удаления концевых пробелов в строке S:

readln(S);

n := length(S);

while S[n]=’ ’ do

n := n-1;

S[0] := chr(n);

для следующих тестовых данных

 

а) S1=

6.000asd

( -символ пробела)

б) S2=

 

 

(ровно 32 пробела)

2) Исправьте код, чтобы он работал корректно для любых входных данных.

18

Пример 8. Дана строка S. Удалить «лишние» пробелы в строке, то есть удалить начальные, концевые пробелы, и внутри строки не должно быть несколько пробелов подряд.

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

(см. Приложение) и оформлен в виде процедуры S81( S, Sr ). Результат форми-

руется в новой строке Sr.

procedure S81(var S, Sr: string); var p:integer;

begin Sr:=S;

if Sr <>'' then begin

p:=pos(' ',Sr);

{повторять, пока есть два подряд идущих пробела} while p<>0 do

begin

delete(Sr,p,1); {удалить первый из двух пробелов} p:=pos(' ',Sr)

end;

{если первый символ Sr - пробел, то удалить его} if Sr[1]=' ' then

delete(Sr,1,1); if Sr<>'' then

{если последний символ Sr - пробел, то удалить его} if Sr[length(Sr)]=' ' then

delete(Sr,length(Sr),1)

end end;

19

Второй вариант решения оформлен в виде функции S82( S ) и использует посимвольную обработку строки S с формированием новой строки Sr : в строку

Sr копируется символ строки S, если он не является пробелом, либо он – пробел,

но предыдущий символ таковым не был.

function S82(var S: string): string; var Sr : string;

i,j:integer; {текущие индексы строк S и Sr }

flag: boolean; {признак того, что предыдущий символ является пробелом}

begin Sr:=’’;

flag: = true; j:=0;

for i:=1 to ord(S[0]) do begin

{если предыдущий символ или текущий символ – не пробел} if not flag or (S[i]<>’ ’) then

begin j:=j+1;

Sr[j]:=S[i]

end;

{flag = true, если предыдущий символ является пробелом} flag:= S[i]= ’ ’

end;

{если последний символ – пробел, то удалить его} if Sr[j]= ’ ’ then j:=j-1;

Sr[0]:=chr(j);

S82:=Sr

end;

20

4 ОБРАБОТКА СЛОВ

Пример 9. Дана строка, состоящая из слов – последовательностей симво-

лов, отличных от пробела и разделённых произвольным количеством пробелов. В начале и в конце строки, состоящей из слов, может быть произвольное количество пробелов. Вывести на печать все слова в порядке их следования в строке.

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

Опишем алгоритм выделения слов.

Ищется первый «непробел» в строке – это будет начало первого слова. Далее в цикле до конца строки повторяются следующие действия:

ищется конец слова (первый пробел после слова или конец строки),

пропускаются пробелы до первого «непробела» (начала следующего слова) или до конца строки.

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

program S_9_1;

var n, k, i: integer;

S, S1: string; {строка и слово} begin

writeln (Введите строку’); readln (S);

n := ord(S[0]); i := 1;

{пропуск пробелов – поиск начала первого слова}

21

while (i<=n) and (S[i]=’ ’) do i := i+1;

while i<=n do {повторять, пока не конец строки S} begin

k := i; {запомнить начало текущего слова}

S1 := ’’;

while (i<=n) and (S[i]<>’ ’) do begin

S1 := S1+S[i];

i := i+1; { поиск конца текущего слова} end;

writeln(S1); {вывод слова}

{пропуск пробелов – поиск начала следующего слова} while (i<=n) and (S[i]=’ ’) do

i := i+1

end

end.

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

Пример 10. Дана строка, состоящая из слов (см. Пример 9). Посчитать ко-

личество слов в строке.

При обработке слов в строке не всегда возникает необходимость в их выде-

лении. В этом случае может фиксироваться конец слова: либо текущий символ Si

отличен от пробела, а следующий Si+1 является пробелом, либо Si – последний символ строки.

22