- •Основы разработки алгоритмов
- •Издание посвящается 400-летию г. Томска
- •1.Рекуррентные алгоритмы
- •Задачи для самостоятельного решения 1
- •2.Подпоследовательности в массиве
- •Задачи для самостоятельного решения
- •3.Упорядоченность в массиве
- •Задачи для самостоятельного решения
- •4.Матрицы
- •Задачи для самостоятельного решения.
- •5.Обработка текста
- •Задачи для самостоятельного решения
- •6.Информационные массивы
- •Задачи для самостоятельного решения.
- •7.Советы по решению задач
- •8.Краткий справочник по языку паскаль Структура программы
- •Типы данных
- •Операторы
- •Литература
4.Матрицы
Вывод змейки. Дана матрица из n строк и m столбцов, причем n > m. Вывести некоторые элементы матрицы в таком порядке, как это указано числами на рисунке (элементы матрицы, обозначенные черточками, выводить не нужно):
1 |
2 |
- |
- |
3 |
4 |
5 |
- |
- |
6 |
7 |
8 |
- |
- |
9 |
10 |
- |
11 |
12 |
13 |
14 |
15 |
16 |
- |
17 |
18 |
- |
- |
19 |
20 |
21 |
- |
- |
22 |
23 |
24 |
. . .
Пусть на вход алгоритма поступают:
1) количество строк – переменная n;
2) количество столбцов – переменная m;
3) матрица (двумерный числовой массив) – переменная A.
Идея алгоритма. Для вывода строк матрицы организуем цикл от 1 до n. На каждом i-м шаге цикла выводится два или три элемента с номерами столбцов от k1 до k2. Вспомогательная переменная p определяет направление сдвига для последующей строки. Если p = 1, то номера k1 и k2 сдвигаются вправо, если p = – 1, то влево.
Трудоемкость алгоритма подсчитать легко: цикл по i выполнится ровно n раз, при этом в цикле выводится максимум три элемента и выполняется фиксированное количество других действий. Таким образом, с точностью до постоянного множителя алгоритм имеет трудоемкость порядка n (линейную).
Алгоритм.
j:=0;
for i:=1 to n do {цикл по строкам}
begin k1:=j; k2:=k1+2;
if j=0 then begin p:=1; k1:=1 end
else if j=m-1 then begin p:=-1; k2:=m end;
for l:=k1 to k2 do write(A[i,l],' ');
j:=j+p
end
Общие числа. Дана целочисленная матрица из n строк и m столбцов. В каждой строке матрицы числа упорядочены по возрастанию. Найти все такие числа, которые встречаются в каждой строке матрицы.
Пусть на вход алгоритма поступают:
1) количество строк – переменная n;
2) количество столбцов – переменная m;
3) матрица (двумерный числовой массив) – переменная A.
Идея алгоритма. Понятно, что числовые значения, встречающиеся в каждой строке матрицы, обязательно присутствуют и в первой строке. Поэтому можно организовать цикл по элементам первой строки и для каждого элемента проверить, что элементы с таким же значением встречаются во всех других строках. Для проверки необходимо организовать цикл по всем другим строкам, и внутри этого цикла, в свою очередь, цикл по элементам строки. При этом следует обеспечить досрочное прекращение циклов, если обнаружится, что в какой-либо строке искомое значение найдено или его заведомо нет.
Если в первой строке встречаются элементы с одинаковым значением, то цикл необходимо организовать не по элементам, а по разным значениям. Так как элементы в первой строке упорядочены, то одинаковые значения всегда располагаются подряд.
Заметим, что в этом алгоритме не использована исходная упорядоченность элементов по строкам.
Трудоемкость алгоритма имеет порядок n * m 2 (кубический). Для каждого элемента первой строки (таких элементов m), просматриваются все (или почти все) элементы матрицы (кроме первой строки), т.е. (n – 1) m элементов.
Ниже приведен описанный алгоритм А и ускоренный (Б).
Алгоритм А.
k:=1;
while(k<=m) do {цикл по различным значениям 1-й строки}
begin
i:=2; p:=1; {если p=0, то в одной из строк, начиная с 2-й по
n-ю нет совпадения с A[1,k]}
while (p=1) and (i<=n) do
begin r:=0; {если r=1, то совпадение найдено}
j:=1;
while (r=0) and (j<=m) do
if A[1,k]=A[i,j] then r:=1 else j:=j+1;
p:=r;
end;
if p=1 then write(A[1,k],' ');
{вывод найденного значения}
k:=k+1; {переход к следующему значению 1-й строки}
while (k<=m) and (A[1,k]=A[1,k-1]) do k:=k+1;
end;
Алгоритм Б.
for i:=2 to n do T[i]:=1; {массив номеров для строк}
k:=1;
while(k<=m)do {цикл по различным значениям 1-й строки}
begin
i:=2; p:=1; {если p=0, то в одной из строк, начиная с
2-й по n-ю нет совпадения с A[1,k]}
while (p=1) and (i<=n) do
begin
while (T[i]<=m) and (A[i,T[i]]<A[1,k]) do T[i]:=T[i]+1;
if (T[i]>m) or (A[1,k]<>A[i,T[i]]) then p:=0;
{если p=0, то совпадение отсутствует}
end;
if p=1 then write(A[1,k],' ');
{вывод найденного значения}
k:=k+1; {переход к следующему значению 1-й строки}
while (k<=m) and (A[1,k]=A[1,k-1]) do k:=k+1;
end;
Трудоемкость алгоритма. Более эффективен алгоритм Б с квадратичной трудоемкостью n * m. В нем используется упорядоченность строк. Просматриваются элементы во всех строках параллельно, с помощью массива номеров просматриваемых элементов в каждой из строк (массива T).
