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

Гладков_Кулютникова Информатика

.pdf
Скачиваний:
29
Добавлен:
29.03.2015
Размер:
998.19 Кб
Скачать

83 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

к := pos (ch, st);

if k <> 0 then begin delete (st, k, 1); insert (‘a’, st, k)

end;

Задача 3. Замените все вхождения ‘лето’ на ‘зима’.

Решение. Используется предыдущее решение до тех пор, пока не останется сочетний ‘лето’ в строке.

repeat

к := pos (‘лето’, st);

if k <> 0 then begin delete (st, k, 4); insert (‘зимa’, st, k)

end;

until k = 0;

Задача 4. Дана текстовая строка, состоящая из нескольких слов, разделенных одним и более пробелами, заканчивающаяся точкой. Выведите на экран все слова, заменив первую букву слова последней.

Решение. Сначала преобразуем строку таким образом, чтобы между соседними словами стояло по одному пробелу, т.е. удалим все лишние пробелы и заменим точку пробелом. Тогда слово будет представлять собой последовательность символов до первого пробела, после чего преобразуем его по указанному правилу и выведедем преобразованную строку на экран.

var st: string;

 

 

i, k, l: integer;

 

 

begin

 

 

writeln(‘задайте строку’);

 

 

readln (st);

 

 

delete (st, length (st), 1);

 

 

st := st + ‘ ‘;

 

 

repeat

 

 

k := pos (‘ ‘, st);

ищем{

два рядом стоящие пробела}

if k <> 0 then delete (st, k, 2);

{и удаляем их}

until k = 0;

 

 

repeat

 

 

k := pos (‘ ‘, st);

ищем{

пробел: все, что до пробела - слово}

insert (st[k-1], st, 1);

{вставляем последнюю букву в первую позицию

слова}

 

write (copy (st, 1, k));

{выводим на экран преобразованное слово}

delete (st, 1, k)

{и удаляем его из строки}

until k = 0;

 

 

end.

 

 

Задача 5. Дана текстовая строка, состоящая из нескольких слов, разделенных одним или более пробелами, заканчивающаяся точкой. Выведите на экран все слова, отличные от последнего, в которых ровно три буквы “ а”.

Решение. Сформируем массив, состоящий из слов строки, считая словом все, что расположено до первого пробела. Затем сравниваем каждый элемент массива строк с последним элементом, в случае несовпадения считаем количество символов “ а” в этом слове. Если их количество равно трем, выводим на экран.

var st: string;

a: array [1..30] of string [20]; i, k, kk, j, l: integer;

84 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

begin

 

 

 

 

writeln(‘задайте строку’);

 

 

 

readln (st);

 

 

 

 

delete (st, length (st), 1);

{заменяем точку на пробел}

st := st + ‘ ‘;

 

 

 

 

l := 0;

{обнуляем счетчик слов}

 

repeat

 

 

 

 

k := pos (‘ ‘, st);

ищем{

позицию пробела}

 

if k <> 0 then begin

l := l + 1;

 

 

 

 

 

 

 

 

a[l] := copy (st, 1, k - 1); {копируем очередное слово в

 

 

 

массив}

 

 

delete (st, 1 k) ;

{и удаляем его из строки}

 

while st[1] = ‘ ‘ do delete (st, 1, 1);

удаляем{

 

 

 

пробелы}

until k = 0;

for i := 1to l - 1 do

if a[i] <> a[l] then begin {сравниваем очередное слово с последним} kk := 0; {обнуляем счетчик “а” в слове}

for j := 1 to length (a[i]) do

if a[i, j] = ‘a’ then kk := kk + 1; if kk = 3 then write (a[i], ‘ ‘);

end;

end.

Задача 6. Задано слово. Проверьте, можно ли переставить в нем гласные и согласные буквы так, чтобы они чередовались.

Решение. Если количество гласных и согласных букв совпадает (в случае четной длины строки) или отличается на единицу (если длина строки - нечетное число), то можно переставить буквы так, чтобы они чередовались. Таким образом, задача сводится к отысканию количества гласных и согласных букв.

var s: string;

kgl, ksgl: integer; {количество гласных и согласных букв} i: integer;

begin

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

if (length (s) = 0) or (length (s) = 1) then writeln (‘переставить нельзя’) else begin

kgl := 0; ksgl := 0;

for i:=1 to length(s) do

if pos(copy(s, i, 1), 'аоуэыяёюеи') <>0 {принадлежит ли буква множеству гласных букв}

then kgl:=kgl+1

else if pos(copy(s, i, 1), 'бвгджзйклмпрстфхцчшщьъ') <>0 then ksgl := ksgl + 1

else writeln (‘обнаружена нерусская буква ’, s[i]); if length (s) mod 2 = o

then if kdl = ksgl then writeln (‘можно переставить’) else writeln (‘нельзя’)

85 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

else if abs (kgl - ksgl) = 1 then writeln (‘можно переставить’) else writeln (‘нельзя’); end;

end.

Задача 7. Задано предложение, состоящее из слов, разделенных одним или несколькими пробелами. Переставьте слова предложения в алфавитном порядке.

Решение. Перепишем слова предложения по одному в элементы одномерного массива. Отсортируем массив по возрастанию и перепишем слова из массива в строку.

const nn=100;

{максимальное количество слов в предложении}

type mas=array[1..nn]of string; {тип массива строк}

var a:mas;

{массив слов предложения}

i,j,

{индексы массивов, i - номер обрабатываемого символа}

k:integer;

{количество слов в предложении, индекс массива слов}

s,

{исходное предложение и результат}

r:string;

{текущее слово предложения, переменная для обмена слов}

begin

 

 

 

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

 

readln(s);

 

 

s := s + ' ';

{добавили пробел в конце для однотипной обработки

 

всех слов}

 

k := 0;

 

{количество слов в предложении}

r := '';

 

{текущее слово}

 

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

{просмотр предложения по два символа}

if (copy (s, i, 1) <> ' ') and (copy (s, i+1, 1) = ' ')

{если текущий символ не пробел, а следующий пробел} then begin r := r + copy(s, i, 1); {дописать символ к слову}

k := k + 1;

{увеличить количество слов}

a[k]:=r;

{записать слово в массив}

r := ''

{подготовить место для следующего

 

слова}

end

else if copy (s, i, 1) <> ' ' then r := r + copy (s, i, 1);

{если текущий символ не пробел, то записать его в слово} {три следующих оператора сортируют массив}

for i := 1 to k - 1 do for j := i + 1 to k do

if a[i] > a[j] then begin r := a[i]; a[i] := a[j]; a[j] := r end;

{сцепление слов из массива в новое предложение} s := '';

for i := 1 to k do s := s + a[i] + ' '; write (s);

end.

Задача 8. В первый день Незнайка написал одну единицу. Во второй - приписал к ней две двойки. В третий приписал три тройки и т.д. всего n дней. Выведите на экран запись Незнайки в несколько строк по m цифр в одной строке, за исключением, быть может, последней.

Решение. Организуем цикл по дням до n. Номер дня будем переводить в строку и посимвольно печатать, при этом считая количество символов. Если количество напечатанных символов кратно m, то переходим на следующую строку.

var s : string;

i, j, n, m, k, l: integer;

86 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

begin

write (‘введите n и m ’); readln (n, m);

l := 0;

for i := 1 to n do begin

str (i, s);

{перевод номера дня в строку}

for j := 1 to i do

{печатаем s i раз}

for k := 1 to length (s) do begin

write (s[k]); l := i + 1;

if l mod m = 0 then writeln;

end;

end;

end.

Задача 9. В первой строке двумерного массива записаны названия животных, во второй строке - континенты, где они водятся. Например:

Слон

Слон

Кенгуру

Африка

Азия

Австралия

Укажите названия животных, которые водятся более, чем на одном континенте. Решение. Будем просматривать массив, и находить животных, которые встречаются

несколько раз, записываем их в массив для печати, предварительно проверив, нет ли там этого животного.

const nn = 50;

type mas2 = array [1..2, 1..nn] of string; mas1 = array [1..nn] of string;

var a: mas2; b: mas1;

i, j, k, l, n, m: integer; f: boolean;

begin

write (‘введите количество животных и континентов’); readln (n);

for i := 1 to n do

begin write (‘введите животное ’); readln (a[1, i]); write (‘введите континент ’); readln (a[2, i]);

end; j := 0;

for i := 1 to n do

begin k := i + 1; f := false;

while (k <= n) and not f do {поиск повторяющихся животных} if a[1, k] = a[1, i]

then f := true else k := k + 1;

if f

then begin l := 1; f := false;

while (l < = j) and not f do {формирование массива} if a[1, i] = b[l] {печати}

then f := true else l := l + 1;

87 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

if not f

then begin j := j + 1; b[j] := a[1,i] end;

end;

end;

for i := 1 to j do writeln (b[i]);

end.

Задача 10. Задана строка, состоящая из слов, разделенных одним или несколькими пробелами. Удалите повторные вхождения каждого слова.

Решение. Выделяем слова, переписываем их в первую строку двумерного массива, во вторую записываем ‘0’ для уникального слова и ‘1’ - для повторяющегося слова. Затем формируем строку, состоящую из элементов первой строки массива, у которых во второй строке записано ‘0’ и распечатываем строку.

const nn = 10;

 

 

 

 

 

type mas = array [1..2, 1..nn] of string;

 

 

 

var a: mas;

 

 

 

 

 

n: integer;

 

 

 

 

 

s, ss: string; {исходная и вспомогательная строки}

 

i, j, k: integer;

 

 

 

 

 

begin

 

 

 

 

 

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

 

 

 

s := s + ‘ ‘;

 

 

 

 

 

j := o; ss := ‘ ‘;

 

 

 

 

 

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

 

 

 

 

if (s[i] <> ‘ ‘) and (s[i + 1] = ‘ ‘)

выделение{

слов}

 

then begin ss := ss + s[i];

 

 

 

 

j := j + 1; a[1, j] := ss; a[2, j] := ‘0’; {в первую строку}

ss := ‘ ‘

 

 

записываем{

слово}

end

{‘0’во второй строке означает, что слово встретилось

 

впервые}

 

 

 

 

else if s[i] <> ‘ ‘ then ss := ss + s[i];

 

 

 

for i := 1 to j - 1 do

 

 

 

 

 

for k := i + 1 to j do

 

 

 

 

 

if (a[2, i] <> ‘1’) and (a[2, k] <> ‘1’) and (a[1, i] = a[1, k])

then a[2, k] := ‘1’;

нашли{

совпавшие слова}

 

s := ‘ ‘;

 

 

 

 

 

for i := 1 to j do

 

 

 

 

 

if a[2,i] <> ‘1’ then s := s + a[1, i] + ‘ ‘; writeln (‘результат ’, s);

end.

Упражнения.

1.Пусть x - строка. Укажите, для каких значений х справедливо равенство: x=’x’.

2.Пусть x и y - строки, причем длина x равна 1. Укажите условие, при котором x + y

=y + x.

3.Пусть а - строка. Найдите строку х, удовлетворяющую условию: а + х = а.

4.Пусть a, b, x - строки и a - начальная часть b. Найдите x из условия: a + x = b + a.

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

88Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

6.Задан список литературных героев. Они перечислены через запятую. Например, Чебурашка, Семь гномов, Буратино, Красная Шапочка. Получите два массива. В первом запишите имена героев, которые состоят из одного слова. Во втором - все остальные.

7.Задано слово. Проверьте, можно ли из него образовать новое слово, состоящее из четырех символов: согласной, гласной, другой согласной и другой гласной.

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

9.Задано предложение без предлогов, слова в котором разделены одним или несколькими пробелами. Напечатайте все возможные перестановки слов в этом предложении. Например, “ Он учит уроки”, “ Он уроки учит”, “ Уроки он учит”, “ Уроки учит он”, “ Учит он уроки”, “ Учит уроки он”.

10.Задан список слов и еще одно слово. Проверьте, все ли слова списка можно образовать из букв заданного слова.

11.Машинистка напечатала немецкий текст. Выясните, какой артикль: der, die или das машинистка печатала чаще всего.

12.Выписаны подряд годы с 1950 по 1997. Найдите цифру, стоящую на к-ом месте.

13.В языке племени “ ОДОДО” две буквы: О и Д. Две фразы считаются эквивалентными, если они получены вычеркиванием сочетаний “ ОД” или “ ООД” или вставкой в любое место фразы сочетаний “ ДДО”. Найдите фразу минимальной длины, эквивалентную заданной.

14.В строке русских символов два рядом стоящих согласных заменяются символом “ а”, а два рядом стоящих гласных заменяются символом “ б”. Дана сторока. Требуется определить, каких символов после ее преобразования останется больше, гласных или согласных.

15.Алфавит языка ТАУ1 состоит из трех гласных a, o, u и трех согласных p, q, s букв. Слово в языке ТАУ1 всегда заканчивается гласной. В слове не могут стоять две гласные рядом. Задается сптсок слов, перечисленных через запятую. Необходимо напечатать слова языка ТАУ1.

ПРОЦЕДУРЫ И ФУНКЦИИ

В тексте песни припев дается только один раз, если нужно его повторить, то указывается одно слово “ припев”, под которым подразумевается текст, приведенный ранее.

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

Более того, рекомендуется большую задачу разбивать на отдельные смысловые задачи (подпрограммы), программировать их отдельно, отлаживать, а затем объединять в единую программу. Использование подпрограмм считается хорошим стилем программирования. При этом уменьшается в целом объем программы и уменьшается время на ее отладку.

Любая программа может содержать несколько подпрограмм, каждая из которых так же может содержать подпрограммы.

В Паскале имеется два вида подпрограмм: процедура (procedure) и функция

(function).

Процедура может возвращать в качестве ответа несколько значений, а функция - только одно. Работа с процедурами и функциями состоит из двух частей:

1) описание процедуры или функции;

89Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

2)вызов ее на исполнение (передача управления компьютером) с одновременной передачей исходных данных, необходимых для работы процедуры или функции.

По окончании работы процедуры или функции управление возвращается за точку вызова (к следующему оператору).

Описание процедуры:

procedure имя [(список параметров)]; oписание данных;

begin

oператоры процедуры или тело процедуры

end;

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

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

Данные, описанные в разделе описания процедуры или функции, называют локальными. Они используются только внутри данной процедуры или функции. Локальные переменные создаются при каждом вызове функции и уничтожаются, когда процедура или функция заканчивает свою работу. Поэтому они недоступны основной программе.

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

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

Описание функции:

function имяф(список_параметров): тип_возвращаемого_значения; oписание данных;

begin

Операторы функции или тело функции; имяф := выражение; {обязательный оператор, формирующий

возвращаемое функцией значение}

end;

Вызов функции осуществляется с помощью указателя функции, который записывается в каком-либо выражении: имяф(список_аргументов). Операторов имяф := выражение может быть несколько в теле функции. Значение, которое вычисляется функцией, задается последним выполненным до завершения работы функции

90 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

оператором. Если такого оператора присваивания нет в функции, то значение функции не определено, что приведет к аварийному завершению программы.

Задача 1. Напишите функцию, определяющую является ли заданный символ русской гласной буквой.

Решение. В качестве параметра в функцию будет передаваться символ. А результат должен определять является или не является (да или нет), т.е. значение функции должно быть логическим.

function gl (ch: char): boolean; begin

gl := pos (ch, ‘аеиоуыэюя’) <> 0;

end;

Задача 2. Даны два действительных числа x, y. Вычислите значение выражения z := (sign x + sign y)· sign (x + y), где sign - функция, определяющая знак числа, т.е.

−1,

a < 0

 

 

a = 0 .

sign a = 0,

 

1,

a > 0

 

Решение. В качестве передаваемого параметра будем использовать значение вещественной переменной. Функция будет принимать значение -1, 0 или 1, т.е. целое.

var x, y, z: real;

function sign (a: real): integer; begin

if a < 0 then sign := -1

else if a = 0 then sign := 0 else sign := 1;

end;

begin {тело основной программы} writeln (‘задайте значения x и y’);

readln (x, y);

z := (sign (x) + sign (y)) * sign (x + y); writeln (‘z = ‘, z);

end.

Упражнение. Решите предложенную задачу без описания функции.

Задача 3. Напишите функцию, определяющую следующее за данным простое число. Решение. Передаваемый параметр - целое число, значение функции - целое число.

function pr (a: integer): integer;

 

var i: integer;

{возможные делители числа}

aa: integer;

{число - кандидат на простое}

 

f: boolean;

{равно true, если нашли простое число}

begin

 

 

f := false;

{простое число еще не нашли}

aa := a;

 

 

repeat

 

 

aa := aa + 1;

 

i := 1;

 

 

repeat

 

 

i := i + 1;

 

until aa mod i = 0;

 

if aa = i then begin f := true; pr := aa end;

{нашли простое число}

until f;

 

 

91 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

end;

Упражнение. Измените функцию так, чтобы она определяла, является ли число простым. С помощью этой функции найдите все простые числа в заданном массиве целых чисел.

Задача 4. Напишите функцию, проверяющую принадлежит ли заданный элемент двумерному массиву. С помощью этой функции проверить все ли элементы одномерного массива принадлежат заданному двумерному.

Решение. Просматриваем двумерный массив, сравнивая каждый его элемент с элементом одномерного массива. Если нашли совпадение, то элемент имеется в двумерном массиве. Напишем две дополнительные процедуры для вывода одномерного и двумерного массивов.

const nn = 5; mm = 5;

type mas2 = array [1..nn, 1..mm] of integer; mas1 = array [1..nn] of integer;

var a: mas2;

{исходный двумерный массив}

b: mas1;

{исходный одномерный массив}

n, m, i, j: integer;

 

f: boolean;

 

function prov (a: mas2; n, m: integer; x: integer): boolean;

{проверяет, принадлежит ли x двумерному массиву}

var i, j: integer;

 

f: boolean;

 

 

begin

 

 

f := false;

{еще не нашли}

i :=1;

 

 

while (i <= n) and not f do

 

begin j :=1;

 

 

while (j <= m) and not f do

 

if a[i, j] = x

 

 

then f := true

{нашли}

 

else j := j + 1;

{переходим к следующему}

if not f then i := i + 1

 

end;

 

 

prov := f

 

 

end;

 

 

procedure wri1 (a: mas1; n: integer);

{вывод одномерного массива} var i : integer;

begin writeln;

writeln (‘одномерный массив’); for i := 1 to n do write (a[i], ‘ ‘)

end;

procedure wri2 (a: mas1; n, m: integer); {вывод двумерного массива}

var i, j : integer; begin

92 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

writeln (‘одномерный массив’); for i := 1 to n do

begin writeln;

for j := 1 to m do write (a[i, j], ‘ ‘); end;

end;

 

 

 

 

begin

{основная программа}

 

 

write (‘введите количество строк и столбцов’);

 

readln (n, m);

 

 

 

for i := 1 to n do

 

 

 

for j := 1 to m do a[i, j] := random (10);

 

 

for i := 1 to n do b[i] := random (10);

{или b[i] := i}

 

wri2(a, n, m);

 

 

 

 

wri1 (b, n); writeln;

 

 

 

f := true;

 

 

 

 

i := `;

 

 

 

 

while (i <= 1) and f do

 

 

 

begin f := f and prov (a, n, m, b[i]);

 

 

if f then i := i + 1;

{если

данный элемент

есть в двумерном

массиве, то переходим к анализу следующего элемента двумерного массива}

end;

 

 

 

 

if f then writeln (‘входят все’)

 

 

else writeln (‘не входит ’, i, ‘элемент’);

 

 

end.

 

 

 

 

Упражнения.

 

 

 

 

1. Напишите

функцию,

проверяющую принадлежит ли

заданный элемент

одномерному массиву. С ее помощью проверить принадлежит ли каждый элемент двумерного массива заданному одномерному. Программа должна быть эффективной и не допускать лишних переборов.

4

ln

2

x

 

2. Найдите значение интеграла

 

методом трапеций, оформив вычисление

x

 

1

 

 

 

 

 

 

подинтегрального выражения в виде функции.

РЕКУРСИЯ

В Паскале есть возможность обращения процедуры или функции к самой себе. При этом получается интереснейший эффект: циклическую часть программы можно представить без операторов цикла.

Способ обращения процедуры или функции к самой себе называется рекурсией. Различают прямую рекурсию, когда процедура или функция содержит явное обращение к себе самой, и косвенную, когда процедура или функция α вызывает процедуру или функцию β, а та в свою очередь вызывает процедуру или функцию α.

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

Таким образом, любая рекурсия обязательно должна содержать два условия:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]