Теоретический материал (Паскаль)

Сайт: Информатикс
Курс: Массивы
Книга: Теоретический материал (Паскаль)
Напечатано:: Гость
Дата: Пятница, 27 Июнь 2025, 09:51

Доступ к элементам массива

Рассмотрите предложенные ниже фрагменты программ для решения некоторых типичных задач.

Изменение значения некоторых элементов

Задача. Заменить отрицательные элементы на противоположные по знаку.

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

Procedure Zamena (Var m : MyArray; n:integer);
Var
  i : integer;
Begin
  for i := 1 to n do
    if m[i] < 0
      then
        m[i] := -m[i];
End;

Нахождение номеров элементов с заданным свойством

Задача. Найти и вывести на экран номера четных элементов.

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

Procedure PoiskChet(m : MyArray; n:integer);
Var
  i : integer;
Begin
  for i := 1 to n do
    if m[i] mod 2 =0
      then
        Write(i:5);
End;

Нахождение количества элементов с заданным свойством

Задача. Найти количество положительных и отрицательных элементов в данном массиве.

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

Procedure OtrPol(m : MyArray; n:integer; Var k1, k2 : Integer);
Var
  i : integer;
Begin
  k1 :=0;
  k2 :=0;
  for i := 1 to n do
    if m[i] > 0
      then
        Inc(k1)
      else
        if m[i] < 0
          then
            Inc(k2);
End;

 Есть ли в данном массиве элементы с данным свойством?

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

Задача. Есть ли отрицательный элемент в массиве?

Начинаем с первого элемента (i=1). Пока не просмотрен последний элемент (i<=n) и не найден отрицательный (m[i]>=0), будем переходить к следующему (Inc(i)). Таким образом, мы закончим просмотр массива в одном из двух случаев: первый – просмотрели все элементы и не нашли отрицательный, тогда i>n, второй – нашли нужный, при этом i<=n. Опишем функцию, значение которой истина (True), если такой элемент есть, и ложь (False), если его нет.

Function Control (m : MyArray; n:integer) : Boolean;
Var
  i : integer;
Begin
  i := 1;
  while (i<=n) and (m[i]>0) do
    Inc(i);
  Control := (i<=n);
End;

Удаление элементов из одномерного массива

Задача. Удалить из массива максимальный элемент, если все элементы разные.

Для того, чтобы решить задачу нужно:

  • найти номер максимального элемента k;
  • сдвинуть все элементы, начиная с k-го, на один элемент влево;
  • последнему элементу присвоить значение 0;
  • уменьшить количество элементов массива на единицу.

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

6, 3, 4, 7, 11, 2, 13, 8, 1, 5.

Номер максимального элемента равен 7 (k=7), то есть, начиная с 7-го элемента, будем сдвигать элементы на один влево: 7-му присвоим значение 8-го, 8-му присвоим значение 9-го, 9-му присвоим значение 10-го, на этом сдвиг заканчивается. Таким образом, сдвиг начинается с k-го элемента и идет по (n-1)-й (где n - количество элементов в массиве). После этого последнему элементу присвоим значение, равное 0, и тогда массив будет следующим:

6, 3, 4, 7, 11, 2, 8, 1, 5, 0.

Примечание. При удалении элемента размерность массива не изменяется.

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

Program DeleteK;
Const
  n=30;
Type
  MyArray = Array [1..n] of Integer;
Var
  A : MyArray;
  k : Integer;

Procedure InsertMas1(Var m : MyArray; n : integer);
  . . .

Procedure InsertMas2(Var m : MyArray; n : integer);
  . . .

Procedure PrintMas(m : MyArray; n : integer);
  . . .

Function Maximum (m : MyArray; n:integer) : Integer;
Var
  i, max, maxi : integer;
Begin
  max:=-maxint; {начальным значением переменной будет наименьшее значение данного типа}
  for i := 1 to n do {просматриваем все элементы массива}
    if m[i] > max {если найден элемент больше, чем тот, что мы считаем максимальным}
      then
        begin
          max:=A[i]; {то запомним найденное значение}
          maxi:=i; {а также место, на котором он стоит в массиве}
        end;
  Maximum := maxi; {имени функции присвоим найденный результат}
End;

Procedure Delete(Var m : MyArray; Var n:integer; k1 : integer);
Var
  i : integer;
Begin
  for i := k1 to n-1 do
    m[i] := m[i+1];
  m[n]:=0;
  Dec(n);
End;

Begin
  . . .
  k:=Maximum(A,n);
  Delete(A,n,k);
  . . .
End.

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

Изменим условие задачи. Пусть максимальный элемент встречается несколько раз.

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

Просмотр элементов массива с конца можно реализовать при помощи цикла с параметром (downto). Кроме того, номер максимального элемента запоминать не будем. При прохождении массива с конца, если элемент имеет максимальное значение, то удалим его, при этом значение счетчика k будем увеличивать на 1.

Задание. С учетом изложенного выше составьте программу, решающую поставленную задачу или дополните предыдущую.

Внимание! Любая Ваша программа должна сопровождаться комментариями.

Вставка элементов в одномерный массив

Вставка одного элемента

Вставлять элемент можно до или после данного элемента, номер этого элемента можно вводить с клавиатуры или искать по определенному условию.

Пусть k - это номер элемента, после которого мы должны вставить элемент х. Тогда вставка осуществляется следующим образом:

  • первые k элементов массива остаются без изменения,
  • все элементы, начиная с (k+1)-го, необходимо сдвинуть на один назад,
  • на место (k+1)-го элемента записываем значение х;
  • увеличиваем количество элементов в массиве на единицу.

Задача. Вставить число 100 после пятого элемента массива.

Рассмотрим конкретный пример. Пусть задан следующий одномерный массив из N (N=10) элементов:

3, -12, 5, 14, 27, -6, 1, -34, 10, -15.

Надо вставить 100 после пятого элемента массива, т. е. должен получиться следующий массив:

3, -12, 5, 14, 27, 100, -6, 1, -34, 10, -15.

Таким образом, в массиве стало 11 элементов, то есть массив надо определять на N+1 элемент:

Type
  MyArray = array[1..n+1] of integer

Кроме того, в программе необходимо выводить массив два раза, сначала первые N элементов массива, а затем полный массив из N+1 элемента.

Рассмотрите процедуру вставки Insert1(m, n, Mesto, Element), которой передаются:

m - массив, в котором делаем преобразования;
n - количество элементов в массиве,
Mesto - номер элемента, после которого надо вставить данный,
Element - число, которое вставляем.

Кроме того, сдвиг элементов будем начинать с последнего элемента.

Program Vstavka1;
Const
  n=10;
Type
  MyArray = array [1..n+1] of integer;
Var
  A : MyArray;
  k, x : Integer;

Procedure InsertMas1(Var m : MyArray; n : integer);
  . . .

Procedure InsertMas2(Var m : MyArray; n : integer);
  . . .

Procedure PrintMas(m : MyArray; n : integer);
  . . .

Procedure Insert1(Var m : MyArray; Var n : integer; Mesto, Element : integer);
Var
  i : integer;
Begin
  for i := n downto Mesto+1 do
    m[i+1] := m[i];
  m[Mesto+1]:= Element;
  Inc(n);
End;

Begin
  . . .
  Writeln('Номер элемента, после которого вставлять > ');
  Readln(k);
  Writeln('Вставляемое число > ');
  Readln(x);
  Insert1(A, n, k, x);
  . . .
End.

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

Вставка нескольких элементов

Задача. Вставить число после всех элементов массива, кратных трем.

Первое, на что необходимо обратить внимание - это описание массива: на сколько элементов может увеличиться массив? Максимальное количество элементов, после которых будет вставлен новый элемент, совпадает с количеством элементов массива, так как может случиться, что все элементы массива отвечают заданному свойству. Поэтому массив может увеличиться в два раза, а значит, соответствующее ему описание будет следующим:

Type
  MyArray[1..2*n] of Integer;

Второе. Если мы будем просматривать массив с начала и вставлять новый после элемента с заданным свойством, то номер последнего элемента каждый раз может меняться, кроме того, будет просматриваться и новый (вставленный) элемент и его необходимо будет пропускать, поэтому решение будет не очень эффективным. Лучше всего просматривать массив, начиная с конца, тогда вставляемый элемент мешать не будет. Кроме того, номер последнего элемента можно будет знать (если знать, сколько элементов вставлено на данный момент), при этом просмотр будет последовательным от N-го до 1-го.

Program VstavkaN;
Const
  n=10;
Type
  MyArray = Array [1..2*n] of Integer;
Var
  A : MyArray;
  k, x, i : Integer;

Procedure InsertMas1(Var m : MyArray; n : integer);
  . . .

Procedure InsertMas2(Var m : MyArray; n : integer);
  . . .

Procedure PrintMas(m : MyArray; n : integer);
  . . .

Procedure InsertN(Var m : MyArray; Var n : integer; Mesto, Element : Integer;);
Var
  i : Integer;
Begin
  for i := n downto Mesto+1 do
    m[i+1] := m[i];
  m[Mesto+1]:= Element;
  Inc[n];
End;

Begin
  . . .
  Writeln('Вставляемое число > ');
  Readln(x);
  k:=0;
  for i:=n downto 1 do
    if A[i] mod 3=0
      then
        InsertN(A, n, i, x);
  . . .
End.

Задание. Дополните программу необходимыми операторами и комментариями и добейтесь работоспособности программы.

Перестановка элементов массива

Перестановка двух элементов

Задача. Поменять местами два элемента массива с номерами k1 и k2.

Рассмотрите процедуру, с помощью которой эта задача легко решается.

Procedure Obmen2(Var m : MyArray; n, k1, k2 : integer;);
Var
  x : integer;
Begin
  x:=m[k1];
  m[k1] := m[k2];
  m[k2] := x;
End;

Перестановка части массива

Задача. Дан одномерный массив А, состоящий из 2n элементов. Поменять местами первую и вторую его половины

Задание. Оформите решение этой задачи, применив процедуру обмена значений Obmen2, рассмотренную выше.

Заметим лишь, что Вы должны поменять местами элементы с номерами 1 и n+1, 2 и n+2 и т.д., последняя пара - n и 2n, а значит, обмен происходит по правилу: элемент с номером i меняется местами с элементом с номером n+i. Эту закономерность следует применить в организации обращения к процедуре обмена. Например, так:

for i := 1 to n do
  Obmen2(A, 2*n, i, i+n,);

Работа с несколькими массивами

В Turbo Pascal можно одним оператором присваивания передать все элементы какого-либо массива другому массиву того же типа, например:

Var
  a, b: array [1 .. 5] of integer;
Begin
  ...
  a:=b;
  ...
End.

После такого присваивания все пять элементов массива a получат значения из массива b.

Рассмотрим одну из типичных задач.

Задача. Найти скалярное произведение двух массивов.

Скалярным произведением двух массивов одинаковой размерности называется сумма произведений соответствующих элементов. Это можно записать так:

a[1]*b[1] + a[2]*b[2] + ... + a[n-1]*b[n-1] + a[n]*b[n],

где n - это количество элементов в массивах (размерность).

Тогда можно составить следующую функцию:

Function Sp (a, b : MyArray; n ; integer) : LongInt;
Var
  i : Integer;
  s : LongInt;
Begin
  s:= 0;
  for i := 1 to n do
    s := s+a[i]*b[i];
  Sp := s;
End;