Рассмотрим этот процесс на примере. Пусть требуется отсортировать массив из пяти элементов 13 6 8 11 3 по возрастанию.
1ый шаг. 13 6 8 11 3
2ой шаг. 6 13 8 11 3
3ий шаг. 6 8 13 11 3
4ый шаг. 6 8 11 13 3
5ый шаг. 3 6 8 11 13
Процедура сортировки.
procedure sort(var x:lin);
var i, j, w:integer;
begin
for i:=2 to n do
begin
w:=x[i]; j:=i-1;
while (j>0) and (w
begin x[j+1]:=x[j]; dec(j) end;
x[j+1]:=w
end;
end;
Задачи.
115. Удалить из одномерного целочисленного массива размерности n первый отрицательный элемент.
116. Удалить из одномерного целочисленного массива размерности n последний чётный элемент.
117*. Удалить из одномерного целочисленного массива размерности n все отрицательные элементы.
118. Вставить число x после первого отрицательного элемента.
119. Вставить число x перед последним отрицательным элементом.
120. Дана последовательность различных действительных чисел a1,…,a10 . Поменять местами максимальный элемент и последний элемент последовательности.
121. Дана последовательность различных действительных чисел a1,…,a10 . Поменять местами минимальный элемент и первый отрицательный элемент последовательности.
122. В одномерном целочисленном массиве размерности n (n=10) поменять местами первую и вторую половины массива.
a1, a2, … a5, a6, … a9, a10 a6, … a9, a10, a1, a2, … a5
123. Дан одномерный целочисленный массив размерности n (n=10). Переставить его элементы следующим образом: поменять местами первые три и последние три элемента, сохраняя порядок их следования.
124*. Дан одномерный целочисленный массив размерности n (n=10). Переставить в обратном порядке элементы массива, расположенные между минимальным и максимальным элементами.
Двумерные массивы. Инициализация. Работа с элементами.
Пример 36. Заполнить двумерный массив размера nm (n строк, m столбцов) целыми числами, введёнными с клавиатуры. Ко всем отрицательным элементам массива прибавить первый элемент соответствующей строки. Вывести преобразованный массив на экран.
const n=4; m=5;
type lin = array[1..m] of integer;
mas = array[1..n] of lin;
var a:mas;
procedure init1_mas(var x:mas);
var i,j:integer;
begin
for i:=1 to n do for j:=1 to m do read(x[i,j])
end;
procedure print_mas(x:mas);
var i,j:integer;
begin
for i:=1 to n do
begin
for j:=1 to m do write(x[i,j]:6);
writeln
end
end;
procedure solve(var x:mas);
var i,j:integer;
begin
for i:=1 to n do
for j:=1 to m do if x[i,j]<0 then x[i,j]:=x[i,j] + x[i,1]
end;
begin
init1_mas(a);
solve(a); print_mas(a);
readln; readln;
end.
Пример 37. Заполнить двумерный массив размера nm (n строк, m столбцов) случайными действительными числами из интервала [-4, 4]. К элементам k1-ой строки прибавить соответствующие элементы k2-ой строки (k1=2, k2=3).
const n=4; m=5;
type lin = array[1..m] of real;
mas = array[1..n] of lin;
var a,b:mas;
procedure init2_mas(var x:mas);
var i,j:integer;
begin
randomize;
for i:=1 to n do for j:=1 to m do x[i,j]:=(-40 + random(81))/10;
end;
procedure print_mas(x:mas);
var i,j:integer;
begin
for i:=1 to n do
begin for j:=1 to m do write(x[i,j]:6:1); writeln end;
writeln;
end;
procedure sum_str(var x:mas; k1, k2:integer);
var j:integer;
begin
for j:=1 to m do x[k1,j]:=x[k1,j]+x[k2,j];
end;
begin
init2_mas(a); print_mas(a);
b:=a; sum_str(b, 2, 3); print_mas(b);
readln;
end.
Пример 38. Заполнить квадратную матрицу размера nn следующим образом:
const n=8;
type mas = array[1..n,1..n] of integer;
var a:mas;
procedure fill(var x:mas);
var i,j:integer;
begin
for i:=1 to n do for j:=1 to n do
if j=n–i+1 then x[i,j]:=i else x[i,j]:=0
end;
procedure print_mas(x:mas);
var i,j:integer;
begin
for i:=1 to n do
begin for j:=1 to n do write(x[i,j]:6); writeln; writeln end;
end;
begin
fill(a); print_mas(a);
readln;
end.
Пример 39. Дан двумерный целочисленный массив размера nm. Напечатать номера строк, все элементы которых чётны.
const n=4; m=5;
type lin = array[1..m] of integer;
mas = array[1..n] of lin;
var a:mas; k:integer;
procedure init1_mas(var x:mas);
var i,j:integer;
begin
for i:=1 to n do for j:=1 to m do read(x[i,j])
end;
function control(y:lin):boolean;
var j:integer; t:boolean;
begin
t:=true; j:=1;
while (j<=m) and t do
begin t:=not odd(y[j]); inc(j) end;
result:=t
end;
begin
init1_mas(a);
for k:=1 to n do
if control(a[k]) then writeln(k);
readln; readln
end.
Пример 40. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен сумме элементов соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с максимальной суммой элементов.
const n=4; m=5;
type lin = array[1..m] of integer;
mas = array[1..n] of lin;
vector = array[1..n] of integer;
var a:mas; rez:vector; nmax:integer;
procedure init1_mas(var x:mas);
var i,j:integer;
begin
for i:=1 to n do for j:=1 to m do read(x[i,j])
end;
procedure print(x:vector);
var k:integer;
begin
for k:=1 to n do write(x[k]:5);
writeln
end;
procedure sum_str(x:mas; var z:vector);
var i,j,s:integer;
begin
for i:=1 to n do
begin
z[i]:=0;
for j:=1 to m do z[i]:=z[i] + x[i,j]
end;
end;
function max_sum(z:vector):integer;
var k, max:integer;
begin
max:=z[1]; result:=1;
for k:=2 to n do
if max
begin max:=z[k]; result:=k end;
end;
begin
init1_mas(a);
sum_str(a, rez); print(rez);
nmax:=max_sum(rez); writeln(nmax);
readln; readln;
end.
Пример 41. Найти произведение двух квадратных матриц размера nn.
const n=4;
type mas = array[1..n, 1..n] of integer;
var a, b, c:mas;
procedure init1_mas(var x:mas);
var i,j:integer;
begin
for i:=1 to n do for j:=1 to n do read(x[i,j])
end;
procedure print_mas(x:mas);
var i,j:integer;
begin
for i:=1 to n do
begin
for j:=1 to n do write(x[i,j]:6); writeln
end
end;
procedure mult(x,y:mas; var z:mas);
var i, j, k:integer;
begin
for i:=1 to n do for j:=1 to n do
begin
z[i,j]:=0;
for k:=1 to n do z[i,j]:=z[i,j] + x[i,k]*y[k,j]
end
end;
begin
init1_mas(a);
init1_mas(b);
mult(a, b, c);
print_mas(c);
readln; readln;
end.
Задачи.
125. Заполнить двумерный массив размера nm (n строк, m столбцов) действительными числами, введёнными с клавиатуры. (Все элементы матрицы различны, среди них есть и положительные, и отрицательные числа).
1) Найти сумму элементов матрицы.
2) Найти количество отрицательных элементов матрицы.
3) Найти максимальный элемент матрицы и его индексы.
4) Найти среднее арифметическое положительных элементов матрицы.
5) Все элементы матрицы, сумма индексов которых кратна 3, заменить нулями.
6) Получить новую матрицу путём деления всех элементов матрицы на её наибольший по модулю элемент.
7) Найти сумму элементов строки, в которой расположен элемент с наименьшим значением.
8*) Найти максимальный среди отрицательных элементов матрицы.
126. Заполнить двумерный массив размера nn (n=5) случайными целыми числами из интервала [-60, 60]. Получить квадратный массив того же порядка, в котором элемент равен единице, если соответствующий элемент исходного массива больше элемента, расположенного в его строке на главной диагонали, и равен нулю в противном случае.
127. Заполнить массив 66 следующим образом:
1 2 3 4 5 6
2 1 2 3 4 5
3 3 1 2 3 4
4 4 4 1 2 3
5 5 5 5 1 2
6 6 6 6 6 1
128*. Заполнить массив 55 следующим образом:
1 -2 3 -4 5
-10 9 -8 7 -6
11 -12 13 -14 15
-20 19 -18 17 -16
21 -22 23 -24 25
129. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен количеству чётных элементов соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с максимальным количеством чётных элементов.
130. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен максимальному элементу соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с минимальным среди максимальных элементов строк.
131. Дан двумерный целочисленный массив размера nm. Напечатать номера строк
1) все элементы которых одинаковы;
2) элементы которых образуют симметричные последовательности;
3) элементы которых образуют возрастающие последовательности.
132. Дана квадратная матрица A размера nn (n=4). Найти A2 + A3.
Динамические массивы
Динамические массивы появились в Delphi 4 и представляют собой удобное средство для хранения данных для тех задач, где заранее неизвестно количество элементов в обрабатываемых массивах.
Объявить динамический массив можно следующим образом:
var <�имя масива> : array of <�тип>;
Например:
var vect : array of real;
Длину массива следует задать при помощи процедуры SetLength. Например:
SetLength(vect, 6);
Данная процедура выделяет для массива vect в оперативной памяти место для 6 вещественных элементов и присваивает этим элементам нулевые значения. Индекс первого элемента равен 0, поэтому массив vect содержит элементы vect[0], vect[1],…, vect[5]. При желании длину динамического массива можно изменить при помощи повторного использования процедуры SetLength. Если новая длина окажется больше исходной, то в массив добавляются новые элементы с нулевыми значениями; если меньше, то последние элементы в исходном массиве будут отброшены.
Переменная, имеющая тип динамического массива, является указателем, т.е. содержит адрес участка памяти, начиная с которого располагаются элементы массива. Поэтому удаление динамического массива может быть осуществлено одним из трёх способов:
1. Присвоить переменной значение nil, например:
vect:=nil;
2. Использовать процедуру finalize, например:
finalize(vect);
3. Установить нулевую длину, например:
SetLength(vect, 0);
Интересной особенностью динамических массивов является то, что можно создавать непрямоугольные массивы, т.е. когда для каждой строки количество столбцов различно. Для этого нужно вначале установить длину первого измерения, а затем, определить длину каждой строки. Например, последовательность операторов
…………………………………….
var r : array of array of integer;
…………………………………….
SetLength(r, 3);
SetLength(r[0], 1);
SetLength(r[1], 2);
SetLength(r[2], 3);
……………………………………..
создаёт треугольный массив.
Параметры-массивы
Типом любого параметра в списке формальных параметров процедур и функций может быть только стандартный или ранее объявленный тип. Поэтому ошибочным будет, например, следующее объявление процедуры:
procedure T(x : array[1..10] of real);
так как в списке формальных параметров фактически объявляется тип-диапазон, указывающий границы индексов массива.
Если в подпрограмму передаётся массив, то следует первоначально описать его тип, например:
type tmas = array[1..10] of real;
procedure T(x : tmas);
…………………………………..
Динамический массив может передаваться в качестве параметра в те подпрограммы, в описании которых соответствующий формальный параметр объявлен как открытый массив, например:
procedure Q(t : array of real; var w : array of array of real);
Начальное значение индекса в открытом массиве равно 0, как и в динамическом. В подпрограмме реальная длина массива может быть определена либо при помощи функции Length – длина массива, либо при помощи функции High – наибольшее значение индекса. Для этих функций справедливо следующее соотношение:
High(<�массив>) = Length(<�массив>) – 1.
В качестве фактического параметра для открытого массива может выступать и статический массив.
Пример 42. Заполнить случайными целыми числами из интервала [-20,20] двумерный целочисленный массив размера nm, где n – случайное число из интервала [2, 5], m=n+1. В каждой строке массива вставить число, равное i100 ( i – номер строки), после третьего элемента.
type matrix = array of array of integer;
var a : matrix;
n, m, i, j : integer;
procedure init_dinmas(var x:matrix);
var i, j:integer;
begin
for i:=0 to n-1 do
for j:=0 to m-1 do x[i,j]:=-20 + random(41);
end;
procedure print_dinmas(x:matrix; nn, mm:integer);
var i,j:integer;
begin
for i:=0 to nn-1 do
begin for j:=0 to mm-1 do write(x[i,j]:5); writeln end;
end;
begin
randomize;
n:=random(4)+2; m:=n+1;
setlength(a, n, m); writeln(n:5, m:5);
init_dinmas(a); print_dinmas(a, n, m);
setlength(a, n, m+1);
for i:=0 to n-1 do
begin
for j:=m-1 downto 3 do a[i, j+1]:=a[i, j];
a[i, 3]:=(i+1)*100;
end;
print_dinmas(a, n, m+1);
readln
end.
Пример возможного варианта выполнения программы:
3 4
-4 -7 7 19
10 -2 5 7
6 -14 6 -3
-4 -7 7 100 19
10 -2 5 200 7
6 -14 6 300 -3
1.7 Строки
Строковые типы
Строка представляет собой набор символов, заключённый в апострофы. Например: abcdef Иванов И.И. 10.0 S =
Константа типа char представляет собой символьную строку единичной длины. Используемые в Object Pascal строковые типы приведены в следующей таблице:
-
Тип строки
|
Максимальная длина
|
Нулевой символ в конце
|
ShortString
|
255 байт
|
Нет
|
AnsiString
|
2 Гб
|
Есть
|
String
|
255 байт / 2 Гб
|
Нет / Есть
|
WideString
|
1 Гб
|
Есть
|
Значение типа ShortString – это так называемые короткие строки, длина которых не превышает 255 символов. Каждый символ занимает один байт, самый первый байт содержит число, указывающее длину строки. Каждый байт имеет свой порядковый номер. Первый байт, содержащий длину строки, имеет номер 0. По номеру символа можно получить доступ к его значению, указав номер символа в квадратных скобках после имени строки.
Например, для строки st , имеющей тип shortstring и значение st = Object , получим:
ord(st[0])=6, st[1]=O, st[2]=b, st[3]=j, st[4]=e, st[5]=c, st[6]=t.
Длина строки, хранящаяся в нулевом байте, представлена в символьном виде, поэтому для преобразования в число следует воспользоваться стандартной функцией ord, а обратно – функцией chr.
Короткая строка размещается компилятором в памяти компьютера до начала выполнения программы, т.е. статически.
Строка типа AnsiString располагается в памяти иначе. Сама переменная типа AnsiString занимает в памяти 4 байта и является указателем, т.е. содержит адрес той ячейки памяти, начиная с которой будет фактически располагаться символьная строка. Выделение места в памяти происходит на этапе выполнения программы, т.е. динамически. Программа сама определяет необходимую длину строки по заданному количеству символов, и операционная система выделяет нужный участок памяти. В конце строки размещается терминальный (завершающий ) нуль – символ #0 и так называемый счётчик ссылок, занимающий 4 байта. Счётчик ссылок позволяет экономить память. Например, если в программе имеется фрагмент:
……………………………………
var s1, s2 : ansistring;
……………………………………
s1 stroka ;
s2 s1;
…………………………………..
то память для размещения переменной s2 не выделяется, а в переменную s2 помещается значение указателя из переменной s1. Счётчик ссылок в области памяти, связанной с переменной s1, увеличивает своё значение на 1 и станет равным 2. В программе может быть несколько переменных, ссылающихся на одну и ту же строку. Счётчик ссылок равняется количеству ссылающихся на строку переменных. Если одна из ссылающихся на строку типа AnsiString переменных изменит своё значение, то в памяти будет выделено место для новой строки. Число ссылок в прежней строке уменьшится на 1, а в новой строке становится равным 1. Если число ссылок на строку станет равным 0, то строка уничтожается и освобождает место в памяти. Нумерация символов в строке типа AnsiString начинается с 1. Процедура SetLength, которую мы использовали для установления длины динамического массива, может быть также использована для установления длины строки типа AnsiString.
Тип String интерпретируется компилятором Object Pascal по-разному, в зависимости от значения директивы компилятора $H. Если она включена – {$H+} – то тип String интерпретируется как AnsiString, если нет – {$H-} – то как ShortString. По умолчанию действует директива {$H+}.
Если в разделе описаний указано, например String[10], то независимо от директив компилятора тип трактуется как ShortString с указанным числом символов.
Тип WideString также представляет собой динамически размещаемые в памяти компьютера строки, длина которых ограничена только объёмом свободной памяти компьютера. Однако в отличие от строки типа AnsiString каждый символ является Unicode-символом, т.е. кодируется 2 байтами.
Пример 43. В строке Ivanov I. дописать полностью имя (Ivan).
var s : ansistring;
begin
s:='Ivanov I.';
setlength(s, 12);
s[9]:='v'; s[10]:='a'; s[11]:='n'; s[12]:='.';
writeln(s);
readln;
end.
Стандартные подпрограммы для строк.
function AnsiCompareStr(const S1, S2 : string): integer;
Сравнивает две строки S1 и S2 в кодировке Ansi с учётом регистра. Возвращает значение меньше 0, если S1S2. В русифицированных версиях Widows может быть применена к строкам, содержащим русские буквы.
function AnsiCompareText(const S1, S2 : string): integer;
Полностью аналогична предыдущей функции за исключением того, что сравнение символов осуществляется без учёта регистра.
function AnsiLowerCase(const S : string): string;
Возвращает в кодировке Ansi строку S, преобразованную к нижнему регистру. В русифицированных версиях может быть применена к строкам, содержащим русские буквы.
function AnsiPos(const Substr, S : string): integer;
Возвращает позицию (индекс) первого вхождения Substr в S. Если Substr не входит в S, то возвращается 0. В русифицированных версиях Windows может быть применена к строкам, содержащим русские буквы.
function AnsiUpperCase(const S : string): string;
Возвращает строку S в кодировке Ansi, преобразованную к верхнему регистру. В русифицированных версиях Windows может быть применена к строкам, содержащим русские буквы.
function Concat(S1, S2…SN : string): string;
Возвращает строку, представляющую сцепление строк S1, S2… SN. Идентична операции + для строк.
function Copy(S; Index, Count: integer): string;
Параметр S – это строка типа string или динамический массив. Функция Copy возвращает подстроку строки S, начинающуюся с символа с номером Index и содержащую Count символов.
procedure Delete(var S : string; Index, Count : integer);
Удаляет из S подстроку, начинающуюся с символа с номером Index и содержащую Count символов.
procedure Insert(Substr : string; S : string; Index : integer);
Вставляет строку Substr в S, начиная с символа с номером Index.
function Length(S : string): integer;
Возвращает число символов в строке S.
function Pos(Substr, S : string): integer;
Возвращает позицию (индекс) первого вхождения подстроки Substr в строку S. Если Substr нет в S, то возвращается 0.
procedure SetLength(var S; NewLength : integer);
Параметр S является строкой или динамическим массивом. Процедура устанавливает новую длину NewLength строки S. Если строка имеет тип ShortString, то значение параметра NewLength должно находиться в диапазоне 0..255. Для длинных строк значение параметра NewLength ограничено лишь размерами доступной памяти компьютера. При увеличении длины строки старые значения, находившиеся там, сохраняются, а во вновь добавленных позициях находятся неопределённые значения.
function StringOfChar(Ch : char; Count : integer): string;
Создаёт строку, состоящую из Count раз повторяющегося символа Ch.
function Trim(const S : string): string;
Удаляет из строки S начальные и завершающие пробелы и управляющие символы.
Строковые выражения
Над строками определены операции отношения. Строки сравниваются по кодам символов. Напомним, что для консольных приложений используется кодировка ASCII, а для оконных – ANSI. При сравнении двух строк последовательно сравниваются коды символов, стоящих в одинаковых позициях. Символы в строках просматриваются слева направо. Если в очередной паре оказываются различные символы, то большей считается та строка, символ которой имеет больший код. На этом сравнение прекращается. Если сравниваются строки разной длины, причём одна строка совпадает с началом другой, то большей будет более длинная строка.
Например,
муха < слон
слон < слоник
2 > 123
Кроме операций отношения над строками определена операция сцепления (конкатенации), которая обозначается знаком + . Например,
Object + Pascal = Object Pascal
Строки разных типов могут смешиваться в одном выражении, переменным одного строкового типа можно присваивать значения другого строкового типа. Компилятор при этом осуществляет автоматическое приведение типов. Если переменной типа ShortString присваивается в качестве значения строка, длина которой больше 255, то лишние символы отбрасываются.
Для ввода символьных строк необходимо использовать процедуру readln, а не read. Это объясняется тем, что в конце каждой символьной строки, вводимой с клавиатуры, стоит так называемый разделитель строк EOLN (end of line) – последовательность кодов #13(CR – перевод каретки) и #10(LF – переход на начало строки). Разделитель строк вставляется во вводимый текст при нажатии на клавишу Enter. Процедура readln считывает все символы, расположенные до разделителя строк, а затем и символы разделителя строк (#13 и #10), которые являются управляющими и переводят курсор дисплея в начало следующей строки.
Пример 44. Используя стандартные функции для строк, получить из строки 'grammofon' строку fonogramma.
var t, s : string; i, j : integer; Комментарий
begin
s:='grammofon';
i:=pos('o', s); i = 6
t:=copy(s, 1, i-1); t = gramm
delete(s, 1, i); s = fon
j:=length(s); j = 3
s:= s + t + 'a'; s = fongramma
insert('o', s, j+1); s = fonogramma
writeln(s); readln
end.
Пример 45. Дана строка s, введённая с клавиатуры. Определить, сколько раз входят в строку английские малые гласные буквы.
var s, v : string;
function glas(w:string; st:string) : byte;
var i:byte;
begin
result:=0;
for i:=1 to length(st) do
if pos(st[i], w)<>0 then inc(result)
end;
begin
v:='aeiouy'; readln(s);
writeln(glas(v, s));
readln
end.
Пример 46. Дана строка s, содержащая не более 20 символов. Удалить все буквы z .
Приведём текст функции, удаляющей из строки s все буквы z .
function solve(st:string):string;
begin
while pos('z', st)<>0 do
begin
delete(st, pos('z', st), 1)
end;
result:=st
end;
Пример 47. Дана строка s. Сформировать строку, состоящую из всех различных строчных английских букв, встречающихся в строке s.
var s, v : string;
function engl(w:string; st:string) : string;
var k, i : byte;
begin
result:='';
for i:=1 to length(st) do
if (pos(st[i], w)<>0) and (pos(st[i], result)=0)
then result:=result + st[i]
end;
begin
v:='abcdefghijklmnopqrstuvwxyz'; readln(s);
writeln(engl(v, s));
readln
end.
Пример 48. Дана строка, содержащая не более 40 символов, являющихся строчными английскими буквами и запятыми. Последний символ – точка. Последовательность букв между двумя соседними знаками препинания назовём словом. Напечатать в столбец по одному все слова из 4 букв.
type slovo = array[1..40] of string;
var s:string; st:slovo; j, n:byte;
procedure spisok(ss:string; var sp:slovo; var k:byte);
var i:byte;
begin
k:=1;
while pos(' , ', ss)<>0 do
begin
i:=pos(' , ', ss);
sp[k]:=copy(ss, 1, i-1); delete(ss, 1, i);
inc(k);
end;
sp[k]:=copy(ss, 1, length(ss)-1)
end;
begin
readln(s);
spisok(s, st, n);
for j:=1 to n do if length(st[j])=4 then writeln(st[j]);
readln
end.
Задачи.
133. Известно, что в строке S есть только одна запятая. Не используя операторы цикла, преобразовать строку S следующим образом: поменять местами части строки S, стоящие до и после запятой.
134. Известно, что в строке S встречается сначала один символ # , а потом один символ . Не используя операторы цикла, преобразовать строку S следующим образом: часть строки S, расположенную между этими символами, перенести в начало строки S.
135. Из строки S удалить среднюю букву, если длина строки нечётная, иначе удалить две средние буквы.
136. Дана строка S, введённая с клавиатуры. Если последний символ строки – точка, то удалить из строки все запятые. В противном случае оставить строку без изменения.
137. Дана строка S, введённая с клавиатуры. Удалить из строки S все предыдущие вхождения последнего символа.
138. Дана строка S, введённая с клавиатуры. Заменить каждую букву z буквой f.
139. Дана строка S, введённая с клавиатуры. После каждой буквы z вставить букву f.
140. Дана строка S, введённая с клавиатуры. Удвоить каждое вхождение в строку буквы t .
141. Дана строка S, введённая с клавиатуры. Сформировать строку, состоящую из всех цифр, встречающихся в строке S.
142. Дана строка S, введённая с клавиатуры. Сформировать строку, состоящую из всех знаков препинания ( ? ! , . : ; ), встречающихся в строке S.
143. Дана строка S, введённая с клавиатуры. Если в ней нет символа , то оставить строку без изменения, иначе каждую из малых латинских букв, предшествующих первому вхождению символа , заменить на цифру 3 .
144. Дана строка S, введённая с клавиатуры. Если в ней нет символа + , то оставить строку без изменения, иначе каждую из цифр, предшествующих первому вхождению символа + , заменить на символ # .
145. Даны три строки S1, S2, S3. Сформировать строку, в которую входили бы в алфавитном порядке по одному разу общие английские буквы трёх данных строк.
146*. Даны две строки S1 и S2, каждая из которых содержит одно английское слово без повторяющихся букв. Проверить, что слово S2 является написанным не более чем с одной ошибкой словом S1 при условии, что ошибка может заключаться в следующем: переставлены две соседние буквы.
147*. Дана строка, содержащая текст, состоящий только из малых английских букв и пробелов. Зашифровать этот текст следующим образом: каждую букву заменить на букву, стоящую на d (d < 26) позиций правее в алфавите. Расшифровать зашифрованный текст. (Считать, что алфавит склеен по кругу: после буквы z идёт буква a .)
148. Дана строка, содержащая не более 40 символов, являющихся строчными латинскими буквами и запятыми. Последний символ – точка. Последовательность букв между двумя соседними знаками препинания назовём словом. Напечатать в столбец по одному:
Все слова.
Все слова, отличные от последнего.
Слова, которые начинаются и заканчиваются одной и той же буквой.
Ту же последовательность слов, но в обратном порядке.
Все слова, меняя местами в каждом слове первую и последнюю буквы.
Все слова, не содержащие сочетание букв th.
Все слова, в которых менее 5 букв.
Все слова, заменив в каждом слове первую букву заглавной.
Слова, имеющие максимальную в данной последовательности длину.
10*) Симметричные слова.
11*) Ту же последовательность слов в алфавитном порядке.
Преобразование строк в числовые типы и обратно.
Задача преобразования строк в числовые типы и обратно для консольных приложений не актуальна, так как процедуры read, readln, write, writeln выполняют эти преобразования автоматически. Основная область применения этих подпрограмм – оконные приложения, при создании которых программист сам должен предусматривать преобразование типов.
procedure Str(x; var s:string);
Преобразует целое или действительное значение x в строку s (параметр x может иметь указание формата вывода).
procedure Val(s:string; var v; var code:integer);
Преобразует строку s в целую или вещественную переменную v. Параметр code равен нулю, если преобразование прошло успешно, в противном случае он равен номер позиции в строке s, где обнаружен ошибочный символ. Например: если s:='95'; , то в результате выполнения val(s,x,d); x = 95, d=0. Если s=a4, то x=0, d=1.
function StrToInt(s:string):integer;
Возвращает целое число, изображением которого является строка s.
function StrToFloat(s:string):extended;
Возвращает вещественное число, изображением которого является строка s.
function IntToStr(n:integer):string;
Возвращает строку, являющуюся изображением целого числа n.
function FloatToStr(n:extended):string;
Возвращает строку, являющуюся изображением вещественного числа n.
function FloatToStrF(n:extended; format; k, m:integer):string; – строка, являющаяся изображением вещественного n в различных форматах;
при вызове функции указываются:
format – формат (способ изображения);
k – общее количество цифр;
m – количество цифр после десятичной точки.
Значениями параметра format могут быть следующие константы:
ffFixed – число представляется в формате с фиксированной десятичной точкой.
ffExponent – научный формат (экспоненциальная форма записи).
ffGeneral – общий цифровой формат.
ffNumber – аналогичен ffFixed, но в изображении числа используется разделитель групп разрядов.
ffCurrency – денежный формат.
Например: если x=3.587 и s:=floattostrf(x, ffFixed, 7, 3); , то s = 3,587 (используется десятичная запятая).
1.8 Множества
Множественный тип представляет собой конечный набор значений некоторого базового типа. В качестве базового типа может использоваться любой порядковый тип, кроме word, integer, longint, int64.
Описание множественного типа имеет вид:
<�имя типа > = set of <�базовый тип>;
Например:
type mn1 = set of A . . Z;
mn2 = set of 1 . . 5;
Значениями переменных множественного типа являются любые подмножества базового множества. Для задания множества используется конструктор множества, представляющий собой список элементов базового множества, разделённых запятыми и обрамлённый квадратными скобками.
Пример.
type digitChar set of 0 .. 9;
digit set of 0 .. 9;
var s1, s2 : digitChar; s3, s4, s5 : digit;
begin
s1[1, 2, 3]; s2[3, 2, 1];
s3[0..3, 6]; s4[4, 5]; s5[3..9]
end.
[] – пустое множество. Над множествами определены операции:
– пересечение множеств.
s3s4=[]; s3s5=[3, 6];
– объединение множеств.
s3+s4=[0 .. 6];
– – разность множеств.
s5 – s4=[3, 6 .. 9];
= – проверка эквивалентности множеств, возвращает true, если множества эквивалентны.
s1=s2
<> – проверка неэквивалентности.
<= – проверка вложения.
s4<=s5 результат true.
in – проверка принадлежности.
7 in s5 результат true.
Стандартные процедуры для работы с множествами:
include(s, i) – включает элемент i базового типа в множество s.
exclude(s, i) – исключает элемент i из множества s.
Использование множеств позволяет сделать программы более эффективными за счёт уменьшения количества различных проверок.
Пример 49. Используя метод Решето Эратосфена напечатать все простые числа из диапазона 1..30.
Суть метода – вычёркиваем из исходного множества [1..30] те числа, которые не являются простыми.
var n : set of 1..30; k, s : integer;
begin
n:=[1..30];
for s:=2 to 15 do
if s in n then
for k:=s+1 to 30 do
if k mod s=0 then exclude(n, k);
for s:=1 to 30 do
if s in n then write(s:3);
readln
end.
Программа работает следующим образом. Вначале s=2. Это значение принадлежит n, поэтому, начиная с числа 3, вычёркиваем все числа, кратные 2. Теперь s=3. Это значение принадлежит n, поэтому, начиная с числа 4, вычёркиваем все числа, кратные 3. Теперь s=4. Это значение уже вычеркнуто из n. Переходим к s=5 и так далее. Вывод на экран элементов полученного множества осуществляем следующим образом: перебираем все элементы базового множества и отбираем для печати те из них, которые принадлежат n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Задачи.
149. Дана непустая последовательность символов. Построить и напечатать множество, элементами которого являются встречающиеся в последовательности:
1) Цифры и знаки арифметических операций.
2) Заглавные латинские буквы от E до T и знаки препинания (, . ; : ! ?).
150. Напечатать все первые вхождения в данный текст строчных латинских букв, сохраняя их взаимный порядок.
151*. Составить программу для решения ребуса ИКС + ИСК = КСИ.
(Нужно найти три целых трёхзначных числа, для которых верно данное равенство, причём каждой букве должна соответствовать определённая цифра.)
1.9 Записи
Запись – это структура данных, состоящая из фиксированного числа компонентов, называемых полями записи. Компоненты (поля) записи могут быть различного типа.
Описание типа запись:
имя типа record список полей end;
Здесь имя типа – правильный идентификатор. Список полей представляет собой последовательность разделов записи, между которыми ставится точка с запятой. Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделённых друг от друга запятыми. За идентификатором ставится двоеточие и описание типа поля.
Пример. Запись в телефонной книге может быть представлена в виде следующей структуры данных:
type tel = record
number : integer;
fio : string[40];
adr : string[60]
end;
var m, v : tel;
Обращение к значению поля осуществляется с помощью идентификатора переменной записи и идентификатора поля, разделённых точкой. Например:
m.number; m.fio; m.adr;
Поля записи используются в программе как обычные переменные соответствующего типа. Например, можно написать
m.numberm.number 1; или m.fio[1]<>Ф
Допускается применение оператора присваивания к записи в целом. Например, vm; После выполнения этого оператора значения полей записи v станут равны значениям соответствующих полей записи m. Логические операции сравнения для записей не определены. Тип запись нельзя использовать для описания типа функции.
Обращение к полям записи имеет несколько громоздкий вид. Для решения этой проблемы в языке Паскаль предназначен оператор присоединения with , который имеет следующий формат:
with переменная типа запись do оператор;
Один раз указав переменную типа запись в операторе with , можно далее работать с именами полей без указания перед идентификатором поля имени записи. Например:
with m do begin number1364; fioПетров end;
Пример 50. Описать тип point для точки на плоскости со следующими полями: буква, обозначающая точку, координата x, координата y. Даны две точки. Найти длину отрезка, соединяющего эти две точки.
type point = record
name : 'A' .. 'Z';
x : real;
y : real
end;
var a, b : point; ab : real;
begin
readln(a.name, a.x, a.y);
with b do
readln(name, x, y);
ab:=sqrt(sqr(b.x – a.x) + sqr(b.y – a.y));
writeln(a.name, b.name, ' = ', ab:5:2); readln
end.
Пример 51. Имеется ведомость n учащихся с оценками за год по информатике. Создать массив из n элементов типа запись с двумя полями: фамилия и оценка. Напечатать фамилии учеников имеющих оценку 4.
const n = 5;
type inf = record
f : string[8];
m : byte
end;
var g : array[1..n] of inf; i:byte;
begin
for i:=1 to n do readln(g[i].f, g[i].m);
for i:=1 to n do with g[i] do
if m=4 then writeln(f);
readln
end.
Задачи.
152. Имеется ведомость n учащихся с оценками за год по информатике. Создать массив из n элементов типа запись с двумя полями: фамилия и оценка.
1) Напечатать данные учеников, фамилия которых начинается с буквы, заданной параметром fam (вводится с клавиатуры).
2) Подсчитать средний балл в группе и напечатать фамилии учеников, у которых оценка выше среднего балла.
153. Пусть имеется описание типа
type time = record
h : 0..23;
m, s : 0..59
end;
и переменная ct, имеющая тип time, описывающая данный момент времени (часы, минуты, секунды). Определить значение переменной nt, описывающей момент времени, который наступит через 1 секунду после момента ct. (Тип TDateTime не использовать).
154*. Пусть имеется описание типа
type year = 1900..2010;
month = 1..12;
day = 1..31;
data = record
y : year;
m : month;
d : day
end;
Определить дату следующего дня. (Учесть смену месяцев, смену года, високосные года. Тип TDateTime не использовать.)
Литература.
1. Кандзюба С.П., Громов В.Н. Delphi 5. Базы данных и приложения. Лекции и упражнения. – К.: ДиаСофт, 2001. – 592 с.
2. Окулов С.М. Основы программирования. – М.: БИНОМ. Лаборатория знаний, 2004. – 424 с.: ил.
3. Фаронов В.В. Система программирования Delphi. – СПб. : БХВ –Петербург, 2004. – 912 с.: ил.
Оглавление
1.1 Основные понятия……………………………………………. 3
1.2 Простые типы…………………………………………………. 8
1.3 Операторы……………………………………………………… 16
1.4 Процедуры и функции………………………………………… 31
1.5 Динамическая память и указатели…………………………. 38
1.6 Массивы………………………………………………………… 40
1.7 Строки………………………………………………………….. 58
1.8 Множества…………………………………………………….. 66
1.9 Записи…………………………………………………………. 68
Литература………………………………………………………… 70
</0></0>