Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Листинг 9.1. Вывод строки в перевернутом виде и по отдельным словам




Обработка строк текста

9.1. Типы данных CHAR и STRING

В Turbo Pascal имеется два типа данных для работы с текстами: О char — литерный или символьный тип;

П String — СТрОКОВЫЙ ТИП ИЛИ ПрОСТО СТрОКЭ.

Символьный тип

Значением переменных символьного типа char является один символ. Каж­дому символу соответствует код символа — целое число в диапазоне от О до 255. Из этого следует, что символьный тип является порядковым. В не­которых языках программирования (С, Java) тип char относят к целым ти­пам, что разумно, т. к. в памяти компьютера нет символов —- есть только их числовые коды. Это первый момент, который важно уяснить — все дейст­вия по обработке символов, в конечном счете, сводятся к действиям над целыми числами, расположенными строго по порядку.

Над данными символьного типа определены следующие операции отноше­ния: =, о, <, >, <=, >=, вырабатывающие результат логического типа.

Обратите внимание — при выполнении всех операций сравнения коды сим­волов сравниваются как обычные целые числа. При этом получается, что любая заглавная буква всегда меньше соответствующей ей строчной, т. к. в кодовой таблице сначала располагаются все заглавные буквы, а затем строчные (см. приложение 2). Точно так же любая буква латинского алфави­та всегда меньше любой буквы русского алфавита, даже если их изображе­ния на экране практически неразличимы (А латинская, А русская).


Для данных символьного типа определены следующие стандартные функции: П chr(x) — возвращает значение символа по его коду;

П ordfch) —- возвращает код заданного символа ch; П pred(ch) — возвращает предыдущий символ; О succ(ch) — возвращает следующий символ;

П upcase(ch) — преобразует строчную букву в заглавную. Обрабатывает буквы только латинского алфавита.

Например:

П ord('A')=65

О спг(128)='Б'

О pred('B'}='A>

CJ succ(T') = 'flr


upcase('n')='N'


 


Строковый тип

Строка — это последовательность символов. Максимальное количество символов в строке (длина строки) может изменяться от I до 255. Пере­менную строкового типа можно определить через описание типа в разделе определения типов или непосредственно в разделе объявления переменных.

Type

ИмяТипа = string [максимальная длина строки];

Var


Идентификатор,


ИмяТипа;


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

типа:

var


Идентификатор,


string[MaKc. длина строки];


ИЛИ var

Идентификатор,...: string;

Если максимальная длина строки не указывается, то она равна 255 байт.

Строковые данные могут использоваться в программе также в качестве кон­стант.

Например:

const stradres = 'ул. Мира, 35'; { строковая константа }

sadr: string[12] = ' ул. Мира' { типизированная константа, ее можно использовать как обычную переменную ]


type str!25 = string [125];

var strl:str!25; { описание с заданием типа }

stl: string; { по умолчанию длина строки = 255 |

st2,st3: string[50];

strnazv: string[280]; { ошибка, длина больше 255 }

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

Строка в языке Turbo Pascal трактуется как массив символов. Для строки из п символов в памяти отводится п+l байт; п байтов — для хранения симво­лов строки, а один дополнительный байт — для значения текущей длины строки. Этот дополнительный байт имеет номер 0, соответственно первый символ строки имеет номер 1, второй — номер 2 и т. д.

Например, переменная sadr типа string [12] хранится в памяти таким обра­зом (табл. 9.1).

Таблица 9.1. Распределение памяти для хранения переменной

Всего строка занимает 13 байтов, из них последние 4 байта оказались неза­нятыми, т. к. реальная длина строки составляет 8 символов, это значение и хранится в нулевом байте строки. Незанятые байты составляют "хвост" строки, в котором может быть любой "мусор", однако программа не будет обращаться к "хвосту", т. к. реальный размер строки ей известен.

(Замечание ~^)

Из этого представления понятно и ограничение на максимальную длину стро­ки — 255 символов, т. к. для хранения длины строки отведен всего один байт (максимальное двоичное число, которое можно уместить в один байт, — восемь подряд идущих единиц, что соответствует десятичному числу 255).

К любому символу в строке можно обратиться как к элементу одномерного массива

array [0.. n] of char

по номеру (индексу) данного символа в строке. Индекс определяется выра­жением целочисленного типа, которое записывается в квадратных скобках, как для массива.

Обратите внимание — в отличие от массивов переменные строкового типа могут участвовать целиком в операторах ввода/вывода.

Например, readln(stl); writeln(st2>;


При вводе строки количество символов в ней определяется автоматически, при этом автоматически заполняется нулевой байт. Для получения длины строки имеется функция length, которая возвращает значение нулевого бай­та строки (см. разд. 9.3).

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

Приведем пример, в котором исходная строка вводится целиком, а выво­дится по отдельным символам (листинг 9.1). В данном случае программа сначала выводит строку в "перевернутом" виде (например, вводим РОЗА, а выводится АЗОР). Затем та же строка выводится в прямом виде, но каждое слово с новой строки. Считаем, что слова разделены пробелами, причем не обязательно одиночными. Обратите внимание на условие, которое проверя­ет начало нового слова. Разбивка строки на слова — это типовое действие со строками.

Листинг 9.1. Вывод строки в перевернутом виде и по отдельным словам

var s:string;

i: integer; begin

write('Введите строку');readln(s);

for i:=length(s) ciownto 1 do write (s[i]);

for i:=l to length(s)-l do

if (s[i]) = ' ') and (s[i+l]<>' ') then writeln

else write(s[i]); readln; end

Еще один пример, в котором выполняется обработка строки как массива символов. Данная программа (листинг 9.2) проверяет правильность расста­новки скобок в выражении (можно считать ее маленькой частичкой компи­лятора, т. к. перед преобразованием любого выражения в исполнимый код всегда проверяется правильность расстановки скобок). В последней главе (см. листинг 13.3) приводится пример программы для решения аналогичной задачи в более сложной постановке.

;•.......... -.................................:................ •;•"".............;•'-'................ '•........... """'.'..............................................................,,,.,..„..................................................... j

^Листинг 9.2. Проверка баланса скобок в скобочном выражении

var k,i:integer;{ k — номер символа, i — для определения баланса скобок)

s:string;


begin

writeln('Введите скобочное выражение:']; readln(s);

k:=l; i:=0;

while (k<=length(s)) and (i>=0) do

begin

{ если i<0, то выражение неправильно: ')' предшествует '(' }

if s[k]-'(' then i:=i+l;

if s[k]='} ' then i:=i-l,-

k:=k+l; ehd;

if i=0 then writeln('Скобки расставлены правильно.')
{ если i>0, то не хватает закрывающихся скобок }
else writeln{'Скобки расставлены неправильно'};
readln * *

end.

Операции над строками

Над строковыми данными допустимы операция сцепления (конкатенации) и операции отношения. Используя строковые переменные, константы, функ­ции и операцию сцепления, можно строить строковые выражения.

9.2.1. Операция сцепления (+)

Применяется для соединения нескольких строк.

Например:

Выражение: 'Turbo' + ' Pascal' + '7.0'

Результат: Turbo Pascal 7.0'

Обратите внимание— операция конкатенации, в отличие от операции сло­жения в математике, не подчиняется известному правилу: "от перестановки слагаемых сумма не меняется", в этой операции каждый из операндов дол­жен находиться строго на своем месте.

Замечание j

Для того чтобы предоставить программистам возможность использовать один и тот же знак операции "+" для работы с данными разных типов, разработчикам компилятора Turbo Pascal пришлось изрядно потрудиться. При обработке тек­ста программы компилятор анализирует типы операндов и формирует для опе­рации "+" различные машинные коды для целых, вещественных и строковых типов. Такое явление в программировании принято называть полиморфизмом. Запомните этот термин— он пригодится на следующих этапах постижения ис­кусства программирования.


Для присваивания строковой переменной результата строкового выражения используется оператор присваивания.

Например: strl:= Труппа учащихся'; str2:= strl + ' школы-лицея';

Приведем пример использования операции конкатенации (листинг 9.3). До­пустим, необходимо дополнить исходную строку справа символом '*' до заданной длины. Такое действие иногда выполняют при формировании важных денежных документов, чтобы нельзя было ничего вписать в пустые места.

[Листинг 9.3.Дополнение строки звездочками '

!...-..;.-...:.........-•.;.!.'..:.:....:... :..:.'...... -...

var s:string;

procedure dopstr(var s:string; n:integer);.

begin

while length(s)<n do s:=s+'*'; end; begin

writeln('Введите строку:');readln(s};

dopstr(s,80); writeln(s); readln end.

Если в тексте процедуры поменять s+' *' на ' *' +s, то строка будет дополнять­ся пробелами не справа, а слева. Было бы разумно добавить в процедуру dopstr еще два параметра: символ, которым следует дополнять строку, и спо­соб дополнения строки (слева, справа, слева и справа равномерно).

Обратите внимание — все строковые типы считаются совместимыми по при­сваиванию, т. е. можно присваивать друг другу значения строк различного размера. К сожалению, размеры строк при этом не контролируются. Если значение переменной после выполнения оператора присваивания превыша­ет по длине максимальный размер, указанный при объявлении, все лишние символы справа отбрасываются, что важно!

Например:

const si:string[13]='Turbo Pascal';

var s2:string[5];

begin

s2:=sl;...

Переменная s2 при этом получит значение 'Turbo', т. к. присваиваемое значение 'Turbo Pascal1 не разместить в тех пяти байтах, которые отведены под символы переменной s2. Фактически операция присваивания будет вы­полнена неверно, хотя никакого сообщения об ошибке не будет выдано.


Замечание

При отладке задач со строками целесообразно помещать в программу директи­ву {$R+}, которая проверяет выход за пределы диапазона изменения индекса. Однако в приведенном выше случае и это не поможет. Остается надеяться только на свою внимательность!

При передаче строки в качестве параметра процедуры совместимость строк разной длины возможна только при отключенной директиве компилятора строгой проверки типов строк ($v-). По умолчанию она включена — {$v+}, поэтому строковые параметры (и формальный, и фактический) должны бьЕТЬ одного размера. Рекомендуем использовать данную директиву, но с осторожностью, т. к. есть риск потери символов справа, если не хватит места в той строке, которая передается в качестве фактического параметра.

Операции отношения

Операции =, <>, >, <, >=, <= выполняют сравнение двух строковых операн­дов и используются в основном при проверке условий. Сравнение строк производится слева направо до первого несовпадающего символа, и та строка считается большей, в которой код первого несовпадающего символа больше. Такой способ сравнения строк называют лексикографическим. Стро­ки считаются равными, если они совпадают по длине и содержат одни и те же символы.

Например:

Выражение: Результат:

'Иванов '='Иванов И.И. ' false

'Иванов'<'Иванов И.И.' true

'program1 >' PROGRAM1 true

Операции отношения над строковыми данными широко используются при обработке массивов строк. Наиболее важными действиями над такими мас­сивами являются:

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

При решении данных задач используются те же самые алгоритмы, что и для числовых массивов (см. разд. 4.2.3), достаточно только заменить тип эле­ментов массива на тип string. Например, при организации электронного телефонного справочника огромный массив абонентов обычно сортируется, и за счет этого можно в считанные секунды найти телефон абонента по его фамилии.


В данном разделе приведем в качестве примера алгоритм слияния двух от­сортированных массивов строк (листинг 9.4). Допустим, происходит слия­ние двух предприятий и требуется объединить списки сотрудников таким образом, чтобы не нарушить алфавитного (лексикографического) порядка.

I Листинг 9.4. Слияние двух отсортированных массивов строк,

const m=4; n=3;

a: array [1..m] of string=('Абрамов1, 'Григорьев', 'Иванов', 'Сидоров' b:array [l..n] of string= ('Васильев', 'Петров ', 'Яковлев');

var crarray [1..m+n] of string;

k, i, j: integer; (индексы трех массивов}

begin

э.

for k:=l to m+n do

{ если индекс i вышел за пределы массива а или b[j]<a[i] }

if (i>ra) or (b[j]<a[ij) then

begin

c[k]:=b[j]; j:=j+l; end else begin

c[k]:=a[i]; i:=i+l; end;

writelnf 'Массив с:');

for k:=l to m+n do write (c[k],' '); readln end.





Поделиться с друзьями:


Дата добавления: 2015-10-27; Мы поможем в написании ваших работ!; просмотров: 1032 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Логика может привести Вас от пункта А к пункту Б, а воображение — куда угодно © Альберт Эйнштейн
==> читать все изречения...

2285 - | 2212 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.013 с.