- •Программирование на языках высокого уровня
- •1. Основные понятия
- •1.1. Алфавит и словарь языка
- •1.2. Скалярные, стандартные типы данных
- •1.3. Встроенные функции
- •1.4. Структура программы
- •2. Программирование вычислительных процессов
- •2.1. Линейные процессы вычислений
- •2.2. Разветвляющийся вычислительный процесс
- •2.3. Программирование циклов
- •3. Программирование данных
- •3.1. Конструирование простых пользовательских типов
- •3.2. Массивы. Регулярные типы
- •3.3. Сортировка одномерного массива
- •3.4. Многомерные массивы
- •4. Работа со строковыми данными
- •4.1 Массив символов
- •4.2 Манипулирование строками string
- •7.4. Массив строк типа string
- •5 Подпрограммы, определенные пользователем
- •5.1 Описание функций
- •5.2 Передача имени объекта в качестве параметра функции
- •5.3 Рекурсивные вычислительные процессы
- •5.4. Описание процедур
4.2 Манипулирование строками string
В языке Паскаль при работе с текстами чаще всего используются короткие строки типа STRING. Стандартные процедуры READLN(St), WRITE(St) и WRITELN(St) поддерживают ввод и вывод строк переменной длины St: STRING.
Объявление и структура строки
Строку можно объявить двумя способами.
• В разделе констант можно сформировать переменную типа STRING и инициализировать ее путем присваивания начального значения в виде текстового литерала.
CONST A: STRING ='Я учусь программировать'; {Длина строки 255 символов}
В: STRING[15] = 'IBM PC {Длина строки 15 символов }
• Второй способ состоит в объявлении строки в разделе VAR. В этом случае в памяти компьютера отводится место для хранения информации в объеме, не превышающем размер строки.
VAR
A:STRING;
В:STRING[15];
С:ARRAY[1..10] OF STRING[25];
В этом объявлении A представляет собой строку максимально возможной длины, занимающую в памяти компьютера 256 байт. Байт с номером 0, то есть А[0], содержит двоичный код равный количеству символов в строке. Остальные байты A[1]...А[255], имеющие номера с 1 по 255, используются для хранения кодов литер, соответствующих ASCII. Строка B резервирует только 16 байт. В остальном она ничем не отличается от строки А. Переменная С представляет собой массив из 10 строк, каждая из которых имеет длину 15 символов. Обратиться к любой строке массива можно так — С[I], где I — номер строки (I = 1..10). Имеется возможность обратиться к любой литере любой строки — C[I, J], где I — номер строки (I = 1..10), a J — номер литеры в строке (J = 1..25).
Ниже перечисляются стандартные операциями над строками, принятые во многих языках программирования.
Сцепка строк
Сцепка строк — построение такой их комбинации, которая представляет единую результирующую строку. Операцией сцепления является знак '+'. Иногда эту операцию называют конкатенацией строк.
Пример 39. Ввести строку ST символов. Построить три строки: SR – содержащую все символы русского алфавита исходной строки в порядке их следования; SL – содержащую латинские символы исходной строки; SP – содержащую все остальные символы. Указать количество символов в каждой из строк.
При решении задач со строками часто пользуются функциями. В рассматриваемой задаче введем пользовательскую функцию UST(X). На вход этой функции подается литера, а на выходе число 1, 2, или 3. Число идентифицирует символ на принадлежность одной из строк латинской, русской или прочих символов соответственно. Поскольку порядок следования символов в выходных строках соответствует исходной строке, то можно организовать арифметический цикл от 1 до N, где N — длина введенной строки текста. На каждом шаге цикла следует классифицировать текущую литеру с помощью функции UST(ST[I]). По результатам анализа оператор CASE направляет вычислительный процесс по одной из трех ветвей, в которых путем сцепки формируются выходные строки SL, SR, SP. Программа завершается выводом на экран каждой строки и ее размера.
PROGRAM PR39;
VAR ST, SL, SR, SP: STRING; I, N: BYTE;
FUNCTION UST(X: GHAR): BYTE; {1 - лат., 2 – рус., 3 - остальные}
CONST AL: SET OF CHAR = ['A'.. "Z", 'a'.. 'z'];
AR: SET OF CHAR = ['A'.. 'Я', 'a'.. 'п' 'p'.. 'я'];
BEGIN
UST := 3;
IF X IN AL THEN UST := 1;
IF X IN AR THEN UST := 2;
END;
BEGIN
WRITELN('Введите строку не более 255 символов');
READLN(ST);
N:= ORD(ST[0]); {Длина исходной строки}
WRITELN('B исходной строке', N:l,' символов');
SR:= ";
SL:= ";
SP:= "; {Инициализация создаваемых строк}
FOR I := 1 ТО N {Просмотр исходной строки}
DO CASE UST(ST[I]) OF
1: SL:= SL + ST[I]; {Формирование латинской строки}
2: SR:= SR + ST[I] {Формирование русской строки}
ELSE SP:= SP + ST[I] {Формирование строки прочих литер}
END; {CASE, FOR}
WRITELN('B латинской строке ', ORD(SL[0]): 1,' символов, текст строки:'); WRITELN(SL);
WRITELN('B русской строке', ORD(SR[0]): 1,' символов, текст строки:'); WRITELN(SR);
WRITELN('B строке прочих литер', ORD(SP[0]): 1,' символов, текст строки:');
WRITELN(SP)
END.
Строки
AL: SET OF CHAR = ['A'.. "Z", 'a'.. 'z'];
AR: SET OF CHAR = ['A'.. 'Я', 'a'.. 'п' 'p'.. 'я'];
описывают AL и AR как (SET OF) множества всех возможных подмножеств элементов исходного множества, включая пустое множество. Например, такое множество, состоящее из трех элементов [A,B,C] включает в себя следующие подмножества: [A,B,C], [A,B], [B,C],[A,C],[A],[B],[C],[]. Соответственно запись 'a'.. 'п' эквивалентна 'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п'.
Проверка IF X IN AL определяет наличие переменной X, в множестве AL.
Поиск подстроки
Поиск подстроки представляет собой анализ, содержит ли исходная (первая St1) строка вторую St2. Если содержит, то определяется порядковый номер литеры в первой строке, являющейся самой левой позицией второй строки. Для поиска используется функция POS(St2, St1), которая (см. табл. 4.1) возвращает целое число N — номер символа в St1, с которого начинается St2, если поиск успешен, и ноль — в противном случае, где St1, St2: String; N: Byte.
Таблица 4.1
Значения St1 |
Оператор |
Результат N |
'АБВГДЕЖЗИ' |
N:=PОS('ДЕЖ', St1); |
5 |
'АБВГДЕЖЗИ' |
N:=POS('ЖЕД', St1); |
0 |
Удаление подстроки
Удаление подстроки представляет собой операцию нахождения результирующей строки из исходной St посредствам удаления N литер, начиная с позиции Poz (см. табл. 4.2). Для удаления используется стандартная процедура DELETE(St, Poz, N), где St исходная строка, Poz — номер первого удаляемого символа, N — число удаляемых литер, где St: String; Poz, N: Byte.
Таблица 4.2
Значения St |
Оператор |
Результат St |
'АБВГДЕЖЗИ' |
DELETE(St, 3, 4); |
'АБЖЗИ' |
'Река Волга' |
DELETE(St, 1, 5); |
'Волга' |
Однако пользоваться процедурой DELETE неудобно, поскольку результат она не возвращает, а только удаляет из строки подстроку. Лучше разработать пользовательскую функцию DEL(St, Poz, N) с теми же параметрами, что и у процедуры DELETE, которая бы возвращала вычисленную строку непосредственно в строковое выражение, откуда она вызывается.
Пример 40. Создать функцию DEL(St, Poz, N), которая возвращает исходную строку St, из которой удалены N позиций, начиная с позиции Poz.
FUNCTION DEL(ST: STRING; POZ, N: BYTE): STRING;
BEGIN
DELETE(ST, POZ, N);
DEL := ST
END;
Пример 41. Ввести строку, подсчитать число символов в строке и, если оно нечетное, удалить символ, стоящий посредине строки. Вывести полученную строку на экран. В программе использовать функцию DEL.
PROGRAM PR41;
VAR ST: STRING; N: BYTE;
FUNCTION DEL(ST: STRING; POZ, N: BYTE): STRING;
BEGIN
DELETE(ST, POZ, N); DEL:=ST
END;
BEGIN
WRITELN('Введите строку не более 255 символов');
READLN(ST);
N:= ORD(ST[0]); {Длина исходной строки}
IF ODD(N) THEN ST:= DEL(ST, N div 2+1,1);
WRITELN(ST)
END.
Выделение подстроки
Выделение подстроки представляет собой операцию построение новой строки (см. табл. 4.3), являющейся последовательностью литер исходной строки, начиная с позиции Poz длиной N. Для выделения подстроки St1 из строки St используется функция COPY(St, Poz, N), которая возвращает St1, где St, St1: String; Poz, N: Byte.:
Таблица 4.3
Значения St |
Оператор |
Результат St1 |
'АБВГДЕЖЗИ' |
St1:= COPY(St, 3, 4); |
'ВГДЕ' |
'Река Волга' |
St1:= COPY(St, 6, 5); |
'Волга' |
Вставка подстроки
Для вставки подстроки St в строку St1 (см. табл. 4.4), начиная с позиции Poz, используется процедура INSERT(St, St1, Poz), где St, St1: String; Poz: Byte.
Таблица 4.4
Значения St |
Значение St1 |
Оператор |
Результат St1 |
'.' |
'-1200' |
INSERT(St, St1, 4); |
'-12.00' |
'Волга' |
'Река' |
INSERT(St, St1, l); |
'Река Волга' |
Часто использование процедуры INSERT оказывается неудобным. Рекомендуется создать пользовательскую функцию INS(St, St1, Poz), которая возвращает строку St1, полученную из строки St1 путем вставки подстроки St с позиции Poz.
Пример 42. Создать функцию вставки подстроки INS(St, St1, Poz), описанную выше.
FUNCTION INS(ST, ST1: STRING; POZ: BYTE): STRING;
BEGIN
INSERT(ST, ST1, POZ);
INS:= ST1
END;
Определение длины строки
Строка St типа STRING отличается от массива символов тем, что содержит один служебный байт памяти с номером ноль St[0], где хранится текущая длина строки, то есть количество информационных байт (литер). Это число N называется длиной строки. Для определения длины строки (см. табл. 4.5) можно использовать стандартную функцию LENGTH(St), где St: string; N: byte.
Таблица 4.5
Значения St |
Оператор |
Результат N |
|
'-12.36502' |
N:= LENGTH(St); |
9 |
|
" |
N:= LENGTH(St); |
0 |
Замена подстроки
Для замены в исходной строке всех вхождений данной подстроки новой подстрокой стандартной функции нет. Поэтому можно использовать пользовательскую функцию ATR(St, St1, St2), которая описана ниже (см. табл. 4.6). Функция обеспечивает поиск подстроки St в строке St1 и замену всех вхождений на подстроку St2, где St, St1, St2: String.
Таблица 4.6
Значения St |
Значение St1 |
Значение St2 |
Оператор |
Результат Stl |
'АВ' |
'РАВЛДОАВЖ' |
'*' |
St1:=ATR(St, St1, St2); |
'Р*ЛДО*Ж' |
'Волга' |
'Река Волга' |
'Нева' |
St1:=ATR(St, St1, St2); |
'Река Нева' |
Пример 43. В исходной строке заменить все вхождения данной подстроки новой подстрокой, используя функцию ATR.
PROGRAM PR43;
VAR S, S1, S2: STRING;
FUNCTION ATR(ST, ST1, ST2: STRING): STRING;
VAR N,N1: BYTE;
BEGIN
N:= LENGTH(ST); {Длина подстроки подлежащей замене}
WHILE POS(ST, ST1) <> 0 DO BEGIN
N1:= POS(ST, ST1); {Первая позиция заменяемой подстроки}
DELETE(ST1, N1, N); {Удаление заменяемой подстроки}
INSERT(ST2, ST1, N1); {Вставка новой подстроки}
END;
WRITELN('Введите исходную строку ST1');
READLN(S1);
WRITELN('Bвeдитe строку подлежащую замене S');
READLN(S);
WRITELN('Введите строку ST2 на которую нужно заменить ST');
READLN(S2);
WRITELN('Peзyльтaт замены ==> ', ATR(S, S1, S2))
END.
Преобразование численного значения вещественного или целого числа в строку
Для преобразования целочисленного I или вещественного числа IR в строку символов St можно использовать стандартную процедуру STR(IR, St), где St: String; IR: Real; I: Integer. При вызове процедуры следует использовать правила форматирования. Вид результирующей строки полностью определяется форматом. Примеры преобразования приведены в табл. 4.7.
Таблица 4.7
Значения IR, I |
Оператор |
Результат St |
-12 |
STR(I:4, St); |
'-12' |
14.2Е+02 |
STR(IR:10, St); |
'1.4200E+03' |
14.2Е+02 |
STR(IR:10:2, St); |
' 1420.00' |
Преобразование строки в вещественное или целое число и помещение результата в переменную
Для преобразования строки St в переменную целого I или вещественного IR типов используется процедура VAL(St, R, Cod), где Cod целочисленная переменная — Cod: Integer; St: String; IR: Real; I: Integer. Если исходная строка St содержит литерал, удовлетворяющий правилам преобразования в переменную заданного типа, то Cod => 0. В противном случае Cod становится равным номеру первой литеры в St, где нарушены правила записи целых или вещественных констант.
Таблица 4.8
Значения St |
Оператор |
Результат IR, I |
Cod |
'-1200' |
VAL(St, I, Cod); |
-1200 |
0 |
'-1200' |
VAL(St, IR, Cod); |
-1.2E+03 |
0 |
'14.2А+02' |
VAL(St, IR, Cod); |
? |
5 |
Функция VAL работает только со строками, имеющими образ десятичного числа. Если необходимо работать с другими системами счисления, то приходится писать пользовательские функции.