Назад Оглавление

Вперед

 

2.2. Регулярные структуры данных

Регулярные структуры данных представляют собой конструкции, позволяющие объединять набор элементов одинакового типа в структуру. Для организации такой структуры необходимо задать тип элементов, размерность структуры и границы по каждому измерению. Идентификация такой структуры приведет к появлению так называемой полной переменной - переменной не скалярного, а производного типа. Для переменных такого типа, помимо операции присваивания однотипных значений, операции и функции не определены. Действию, обратному организации регулярной структуры, является селектирование, которое состоит в позиционировании на конкретный элемент структуры. Оно состоит в указании индексов элемента и приводит к появлению частичной переменной. Для этой переменной определены операции в соответствии с ее типом. Значения индекса должны образовывать конечное множество упорядоченных значений, поэтому, в качестве индексов могут использоваться все порядковые типы, за исключением длинного целого и поддиапазонов  длинного  целого. Массив хранится в виде непрерывной последовательности переменных, каждая из которых имеет тип массива. Элементы с наименьшими индексами хранятся в младших адресах памяти. Многомерный массив хранится таким образом, что правый индекс возрастает быстрее.

Векторы

     Векторы представляют собой одномерные регулярные структуры.

     Типичной задачей является упорядочение - сортировка - элементов вектора. Ниже представлена так называемая обменная сортировка.

...

for Index1:= 1 to HightPoint - 1 do

  begin

    Minimum:= Vector [ Index1 ];

    Location:= Index1;

    for Index2:= Index1 + 1 to HightPoint do

      begin

        if Minimum> Vector [ Index2 ] then

          begin

            Minimum:= Vector [ Index2 ];

            Location:= Index2

          end

        Vector [ Location ]:= Vector [ Index1 ];

        Vector [Index1 ]:= Minimum

      end

...

     Каждый элемент вектора (и регулярной структуры вообще) имеет два атрибута - значение собственно элемента и индекс элемента.

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

     Разберем решение типичной задачи, связанной с обработкой векторов.

Текст задания

     Даны следующие описания:

const n= 500;

var x: array [ 1..n ] of Integer;

    p: Integer;

    k: 0..n;

     Элемента массива x упорядочены по возрастанию. Требуется присвоить переменной k номер элемента массива x, равного числу p, или 0, если такого элемента нет. Использовать следующий метод двоичного (бинарного) поиска: сравнить p со средним элементом массива (или элементом около середины); если эти числа равны, поиск завершается, если же p меньше среднего элемента, то p надо искать в левой половине массива, а иначе √ в правой; к выбранной половине применяется тот же алгоритм.

Решение

program VectorSample;

const

  n= 500;

var

  x: array [ 1..n ] of Integer;

  p: Integer;

  k, t, m, r: 0..n;

begin

  writeln( 'Введите p');

  readln( p );

  for k:= 1 to n do x[ k ]:= k;

  k:= 0;

  t:= 1; {левая граница отрезка}

  r:= n; {правая граница отрезка}

  {поиск p среди x [t..r]}

  repeat

    m:= ( t + r ) div 2; {середина отрезка t..r}

    if x[ m ]= p then k:= m else

      {замена t..r на m + t..r или t..m - 1}

      if p > x[ m ] then t:= m + 1 else r:= m - 1

  until ( k <> 0) or ( t > r );

  for t:= 1 to n do write( x[ t ] : 5 );

  writeln;

  writeln( 'Результат - ', k)

end.

Варианты заданий

1.      const n = 1000; var s: packed array [1..n] of char; Вывести те элементы массива s, индексы которых являются числами Фибоначчи (1, 2, 3, 5, 8, ┘).

2.      Дан текст из 80 литер. Вывести сначала все цифры, входящие в него, а затем все остальные литеры, сохраняя при этом взаимное расположение литер в каждой из этих двух групп.

3.      const n = 100; var x: array [1..n] of real; преобразовать массив x по следующему правилу (x'k - значение k-того элемента массива после преобразования): x'k = max xi при 1 <= i <= k.

4.      const n = 1000; var s: packed array [1..n] of char; Вывести те элементы массива s, индексы которых являются полными квадратами (1, 4, 9, 16, ┘).

5.      const n = 100; var x: array [1..n] of real; преобразовать массив x по следующему правилу (x' k - значение k-того элемента массива после преобразования): элементы массива циклически сдвинуть на одну позицию влево: x'n = x1, x'k = xk+1, при k = 1, 2, ┘, n-1.

6.      var x, y: array [1..70] of real; k: 1..69; Воспользовавшись массивом y как вспомогательным, элементы массива x циклически сдвинуть на k позиций влево.

7.      Даны координаты n точек на плоскости: x1, y1, ┘, xn, yn (n = 20). Найти номера двух точек, расстояние между которыми наибольшее (считать, что такая пара точек единственная).

8.      Даны две последовательности по 30 целых чисел в каждой. Найти наименьшее среди тех чисел первой последовательности, которые не входят во вторую последовательность (считая, что хотя бы одно такое число есть).

9.      Дана последовательность из 20 целых чисел. Определить количество инверсий в этой последовательности (т.е. Таких пар элементов, в которых большее число находится слева от меньшего: xi > x j при i < j).

10.  Дана непустая последовательность слов из строчных латинских букв; между соседними словами - запятая, за последним словом - точка. Вывести все буквы, которые входят в наибольшее количество слов этой последовательности.

11.  Напечатать заданный текст из 100 литер, удалив из него повторные вхождения каждой литеры.

12.  Определить, сколько различных литер входит в заданный текст, содержащий более 100 литер и оканчивающийся точкой (сама точка в текст не входит).

13.  Дан текст из строчных латинских букв, за которым следует точка. Вывести в алфавитном порядке все буквы, которые входят в этот текст по одному разу.

14.  const n = 1000; var s: packed array [1..n] of char; Вывести те элементы массива s, индексы которых являются степенями двойки (1, 2, 4, 8, ...).

15.  Дан непустой текст из цифр, за которыми следует точка. Напечатать цифру, наиболее часто встречающуюся в этом тексте.

16.  Дано 100 вещественных чисел. Распечатать их в обратном порядке по 6 чисел в строке.

17.  Дан текст, содержащий от 1 до 70 букв, за которым следует точка. Вывести текст в обратном порядке.

18.  const n = 100; var x: array [1..n] of real; элемента массива расположить в обратном порядке.

19.  const n = 100; var x: array [1..n] of real; преобразовать массив x по следующему правилу (x'k - значение k-того элемента массива после преобразования): x'1 = x 1, x'n = xn, x'k = (xk-1 + xk + xk+1)/3 при k = 2, 3, ┘ n-1.

20.  Дан текст из 80 литер. Определить, симметричен ли он, т.е. читается ли он одинаково слева направо и справа налево.

21.  const n = 100; var x: array [1..n] of real; элементы массива циклически сдвинуть на две позиции влево.

22.  var x, y: array [1..70] of real; k: 1..69; Воспользовавшись массивом y как вспомогательным, все отрицательные элементы массива x перенести в начало, а все остальные - в конец, сохраняя при этом исходное взаимное расположение, как среди отрицательных, так и среди остальных элементов.

23.  Дана последовательность из 100 различных целых чисел. Найти сумму чисел этой последовательности, расположенных между максимальным и минимальным числами (в сумму включить оба этих числа).

24.  По заданным коэффициентам многочлена 15-й степени и многочлена 8-й степени определить произведения этих многочленов.

25.  По заданным коэффициентам многочлена P( x ) 10-й степени и многочлена Q( x ) 6-й степени определить коэффициенты многочлена P( Q( x ) ).

26.  const n = 100; var x: array [1..n] of real; Упорядочить массив x по неубыванию (т.е. переставить его элементы так, чтобы выполнялось xk <= xk+1), используя метод сортировки выбором: отыскивается максимальный элемент и переносится в конец массива; затем этот метод применяется ко всем элементам, кроме последнего (он уже находится на своем окончательном месте), и т.д.

27.  const n = 100; var x: array [1..n] of real; Упорядочить массив x по неубыванию (т.е. переставить его элементы так, чтобы выполнялось xk <= xk+1), используя метод сортировки обменом: последовательно сравниваются пары соседних элементов xk и xk+1 (k= 1, 2, 3, ┘,n-1) и, если xk > xk+1, то они переставляются; тем самым наибольший элемент окажется на своем месте в конце массива; затем этот метод применяется ко всем элементам, кроме последнего, и т.д.

28.  const n = 100; var x: array [1..n] of real; Упорядочить массив x по неубыванию (т.е. переставить его элементы так, чтобы выполнялось xk <= x k+1), используя метод сортировки вставками: пусть первые k элементов массива уже упорядочены по неубыванию; берется (k + 1)-й элемент и размещается среди первых k-элементов так, чтобы упорядоченными оказались уже k+1 первых элементов; этот метод применяется при k от 1 до n √ 1.

29.  const n= 40; var x: array [1..n] of integer; y, k: integer; t: boolean; Переменной t присвоить значение true, если в массиве x нет нулевых элементов и при этом положительные элементы чередуются с отрицательными, и значение false иначе.

30.  const n= 40; var x: array [1..n] of integer; y, k: integer; t: boolean; Переменной k присвоить либо номер первого вхождения y в массив x, либо число n + 1, если y не входит в x.

Матрицы

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

     Рассмотрим для примера умножение двух матриц размера nxn

...

for Index1:= 1 to n do

  for Index2:= 1 to n do

    begin

      Result [ Index1, Index2 ]:= 0;

      for Index3:= 1 to n do

        Result [ Index1, Index2 ]:= Result [ Index1, Index2 ]

                                    + Matrix [ Index1, Index3 ]

                                    * Matrix [ Index3, Index2 ]

    end

...

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

     Разберем решение типичной задачи, связанной с обработкой матриц.

Текст задания

     Дана вещественная матрица размером 20 Х 30. Упорядочить ее строки по неубыванию их первых элементов.

Решение

program MatrixSample;

const

  n= 20;

  m= 30;

type

  Row= array [ 1..m ] of Real;

  Matrix= array [ 1..n ] of Row;

var

  A: Matrix;

  x: Row;

  i, j, k: Integer;

begin

  {ввод A}

  for i:= 1 to n do

    for j:=1 to m do

      read ( A[ i, j ] );

  {сортировка выбором}

  for k:= n downto 2 do

    begin {поиск j √ номера max A[ 1..k, 1]}

      j:= 1;

      for i:= 2 to k do

        if A[ i, 1 ] > A[ j, 1 ] then j:= i;

      {перестановка k-ой и j-ой строк}

      x:= A[ k ];

      A[ k ]:= A[ j ];

      A[ j ]:= x

    end;

  {вывод A}

  for i:= 1 to n do

    begin

      writeln ( i, '-я строка:');

      for j:= 1 to m do

        write ( A[ i, j ] );

      writeln

    end

end.

Варианты заданий

1.      Дана квадратная матрица n- ного порядка (n = 6). Найти матрицу, обратную ей, или установить, что такой не существует. (Замечание: если линейными преобразованиями строк привести заданную матрицу к единичной, то этими же преобразованиями единичная матрица будет приведена к искомой обратной матрице.)

2.      Даны координаты n векторов n- мерного линейного пространства (n = 7). Определить, являются ли они линейно независимыми.

3.      По заданным коэффициентам Aij и правым частям bi решить систему линейных уравнений

                         

           считая что ее определитель отличен от нуля. (Рекомендация: систему предварительно привести к ╚треугольному╩ виду.)

4.      Дана непустая последовательность слов из строчных латинских букв; слова разделяются запятыми, за последним словом √ точка. Среди всех пар ai и bj, где ai √ первая, а bj √ последняя буквы i- го слова последовательности, определить наиболее часто встречающуюся пару.

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

6.      Определить, является ли заданная целая квадратная матрица 10- го порядка ортонормированной, т.е. такой, в которой скалярное произведение каждой пары различных строк равно 0, а скалярное произведение каждой строки на себя равно 1.

7.      Дана вещественная матрица размером 7Х7, все элементы которой различны. Найти скалярное произведение строки, в которой находится наибольший элемент матрицы на столбец с наименьшим элементом.

8.      Элемент матрицы назовем седловой точкой, если он является наименьшим в своей строке и одновременно наибольшим в  своем столбце или, наоборот, является наибольшим в своей строке и наименьшим в  своем столбце. Для заданной целой матрицы размером 10Х15 вывести индексы всех ее седловых точек.

9.      Определить, является ли заданная целая квадратная матрица 10-го порядка симметричной относительно главной диагонали.

10.  const n= 256; type screen= array [1..n, 1..n] of 0..1; var S: screen; Преобразовать массив S, осуществив поворот элементов вокруг его центра на 90 градусов против часовой стрелки.

11.  type name= (George, Alex, Piter, Ann, Paul, John, Fred, Natalie, Robert); family= (son, daugther, father, mother, no); var TP: array [name, name] of family; i, v, d: name; k: integer; На основе непротиворечивой таблицы родства TP (TP[x, y]= no, если y не является ни родителем, ни ребенком x, TP[x, y]= son, если y- сын x, и т.п.) присвоить переменной v- имя одной (любой) из внучек человека с именем i, если такие есть.

12.  type name= (George, Alex, Piter, Ann, Paul, John, Fred, Natalie, Robert); family= (son, daugther, father, mother, no); var TP: array [name, name] of family; i, v, d: name; k: integer; На основе непротиворечивой таблицы родства TP (TP[x, y]= no, если y не является ни родителем, ни ребенком x, TP[x, y]= son, если y- сын x, и т.п.) присвоить переменной d- имя одного (любого) из дядей человека с именем i, если такие есть (дядями считать только братьев родителей).

13.  type name= (George, Alex, Piter, Ann, Paul, John, Fred, Natalie, Robert); family= (son, daugther, father, mother, no); var TP: array [name, name] of family; i, v, d: name; k: integer; На основе непротиворечивой таблицы родства TP (TP[x, y]= no, если y не является ни родителем, ни ребенком x, TP[x, y]= son, если y- сын x, и т.п.) присвоить переменной k- количество всех кузин и кузенов (двоюродных сестер и братьев) человека с именем i.

14.  Дана вещественная матрица размером 20Х30. Упорядочить ее строки по неубыванию суммы их элементов.

15.  Дана вещественная матрица размером 20Х30. Упорядочить ее строки по неубыванию их наибольших элементов.

16.  var k: integer; C: array [1..13, 1..18] of char; Определить k- количество различных элементов массива C (повторяющиеся элементы считать один раз).

17.  const n= 8; m= 12; var k: integer; C: array [1..n, 1..m] of integer; Определить k- количество ╚особых╩ элементов массива C, считая элемент ╚особым╩, если он больше суммы остальных элементов столбца.

18.  const n= 8; m= 12; var k: integer; C: array [1..n, 1..m] of integer; Определить k- количество ╚особых╩ элементов массива C, считая элемент ╚особым╩, в его строке слева от него находятся элементы, меньшие его, а справа - большие.

19.  var A: array [1..15, 1..20] of integer; b: array [1..15] of boolean; По массиву A получить массив b, присвоив его k-тому элементу значение true, если все элементы k- го столбца массива A нулевые, и значение false иначе.

20.  var A: array [1..15, 1..20] of integer; b: array [1..15] of boolean; По массиву A получить массив b, присвоив его k-тому элементу значение true, элементы k- той строки упорядочены по убыванию, и значение false иначе.

21.  var A: array [1..15, 1..20] of integer; b: array [1..15] of boolean; По массиву A получить массив b, присвоив его k-тому элементу значение true, k- ая строка массива A симметрична, и значение false иначе.

22.  var A: array [1..20, 1..20] of boolean; B: array [1..19, 1..19] of boolean; n, k: 1..20; Получить массив B из массива A удалением n- ной строки и k- ого столбца.

23.  type month= ( jan, feb, mar, apr, may, jun, jul, aug, sep, okt, nov, dec); day= (mo, tu, we, th, fr, st, sn); calen= array [month, 1..31] of day; var K: calen; Заполнить календарь K соответствующими днями недели (для несуществующих дат указатель no) при условии, что год не високосный и 1 января √ понедельник (K[jan, 1]:= mo; K[jan, 1]:= tu; ┘ K[feb, 29]:= no; ┘).

24.  var A: array [1..6, 1..9] of real; x: array [1..9] of real; Заполнить массив A по следующему правилу: Aij= xij.

25.  type vector= array [1..20] of integer; matrix= array [1..20] of vector; var A: matrix; x: vector; B: array [1..20, 1..20] of integer; Нечетные строки матрицы A заменить на x.

26.  type vector= array [1..20] of integer; matrix= array [1..20] of vector; var A: matrix; x: vector; B: array [1..20, 1..20] of integer; Четные столбцы матрицы A заменить на x.

27.  type vector= array [1..20] of integer; matrix= array [1..20] of vector; var A: matrix; x: vector; B: array [1..20, 1..20] of integer; Первые шесть строк массива B заменить на x.

28.  type vector= array [1..20] of integer; matrix= array [1..20] of vector; var A: matrix; x: vector; B: array [1..20, 1..20] of integer; В матрице A поменять местами 1-ю и 2-ю строки, 3-ю и 4-ю строки, ┘, 19-ю и 20-ю строки (воспользоваться x как вспомогательным массивом).

29.  type vector= array [1..20] of integer; matrix= array [1..20] of vector; var A: matrix; x: vector; B: array [1..20, 1..20] of integer; В матрице B поменять местами 1-й и 2-й столбцы, 3-й и 4-й столбцы, ┘, 19-й и 20-й столбцы (воспользоваться x как вспомогательным массивом).

30.  Даны натуральное n и (построчно) элементы квадратной вещественной матрицы A 5-го порядка. Вычислить n-ю степень этой матрицы (A1=A, A2= AA, A3= A2A и т.д.)

Назад Оглавление

Вперед