Главная страница
Навигация по странице:

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

  • Замечание (

  • Задача

  • ит. ит экз. Решение. Последний отрицательный это первый отрицательный элемент, если начать просмотр с конца


    Скачать 62.45 Kb.
    НазваниеРешение. Последний отрицательный это первый отрицательный элемент, если начать просмотр с конца
    Дата06.12.2022
    Размер62.45 Kb.
    Формат файлаdocx
    Имя файлаит экз.docx
    ТипРешение
    #830164

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

    Пример 1. Найти номера четных элементов.

    Решение.

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

    Procedure Solve(m : myarray);

    Var i: Integer;

    Begin

    For i:=1 To n Do

    If m[i] Mod 2 = 0 Then Write(i:5);{если элемент четный, то вывести на экран}

    End;

    Пример 2. Есть ли отрицательный элемент в массиве?

    Решение.

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

    Начинаем с первого элемента (i = 1).

    Пока не просмотрен последний (i<=n) и не найден отрицательный (m [i]>=0), будем переходить к следующему (inc (i)).

    Таким образом, мы закончим просмотр в одном из двух случаев:

    первый — просмотрели все элементы и не нашли отрицательный, тогда i>n;

    второй — нашли нужный, при этом i<=n.

    Напишем функцию, значение которой истина (True), если такой элемент есть, и ложь (False), если его нет.

    Function Controll (m: myarray): Boolean;

    Var i : Integer;

    Begin

    i := 1;

    While (i<=n) And (m[i]>0) Do Inc(i);

    Control1:=(i<=n)

    End;

    Пример 3. Найти номер последнего отрицательного элемента массива.

    Решение.

    Последний отрицательный — это первый отрицательный элемент, если начать просмотр с конца.

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

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

    Договоримся, что если такого элемента нет, то значение функции будет равно 0.

    Function Control2 (m: myarray): Integer;

    Var i : Integer;

    Begin

    i:=n;

    While (i>=1) And (m[i]>0) Do Des(i);

    If i<1 Then Control2:=0

    Else Control2:=i;

    End;

    Вы рассмотрели алгоритмы на поиск и выборку элементов в массиве.

    На следующем уроке продолжим знакомиться с алгоритмами  обработки одномерных массивов.

    2. Двоичный поиск в упорядоченном массиве

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    uses crt;

    const N=10;

    var i, L,R,M:integer;

    x:array[1..N]of char;

    a:char;

    begin

     for i:=1 to 10 do

     read(x[i]);

     readln;

     L:=1;

     R:=N+1;

     write('Нужный символ -> ');

     readln(a);

      while R-L<>1 do

     begin

      M:=L+(R-L) div 2;

      if x[M]<=a then L:=M else R:=M;

     end;

     if (R>L) and (a=x[l]) then writeln('X[',L,']=',a) else writeln('ничего не найдено');

     readln;

    end.

    Сортировка массива и бинарный поиск

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

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

    Алгоритм бинарного поиска осуществляется исключительно для отсортированных по возрастанию или убыванию массивов и заключается в следующем. Берется элемент в середине массива. Если искомый элемент больше взятого из середины (в случае массива отсортированного по возрастанию), то далее поиск будет продолжен в правой части от среднего; если меньше, то в левой. Эта часть далее снова делится пополам и сравнивается ее середина с искомым элементом и т. д. В конце концов если искомый элемент есть в массиве, то очередная середина отрезка массива с ним рано или поздно совпадет. Если же его нет, то границы отрезка поиска пересекутся и цикл поиска следует прервать.

    Программа на языке Паскаль: 

    const N = 20;

    type arr = array[1..N] of integer;

    var

    a: arr;

    i: byte;

    p,q,e: integer;

    procedure fill(var b: arr; min,max: integer);

    var k: byte;

    begin

    randomize;

    for k:=1 to N do b[k] := random(max-min) + min;

    end;

    procedure search(var c: arr; elem: integer);

    var m,i,j: integer;

    begin

    m := N div 2;

    i := 1;

    j := N;

    while (c[m] <> elem) and (i <= j) do begin

    if elem > c[m] then i := m + 1

    else j := m - 1;

    m := (i+j) div 2;

    end;

    if i > j then writeln('No')

    else writeln('Yes');

    end;

    procedure sort(c: arr; elem: integer);

    var j,k,m,id: byte;

    begin

    m := N;

    while m > 1 do begin

    id := 1;

    for j := 2 to m do

    if c[j] > c[id] then id := j;

    k := c[id];

    c[id] := c[m];

    c[m] := k;

    m := m - 1;

    end;

    search(c,elem);

    end;

    begin

    write('Min: '); readln(p);

    write('Max: '); readln(q);

    write('Element: '); readln(e);

    fill(a, p,q);

    sort(a, e);

    for i:=1 to N do write(a[i],' ');

    writeln;

    end.

    Примеры выполнения программы:

    Min: 10

    Max: 25

    Element: 15

    No

    13 17 24 16 22 22 13 17 24 23 24 24 10 18 10 12 16 20 10 20

    Min: 10

    Max: 25

    Element: 15

    Yes

    18 10 19 14 21 15 15 11 21 17 21 18 17 16 24 16 14 20 10 14

    3. Циклический сдвиг элементов массива

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

    Например, дан массив:
    1 2 3 4 5 6
    Кольцевой сдвиг вправо на 2 единицы:
    5 6 1 2 3 4

    Описание переменных:

    a, m - массив (m - в процедуре);

    q, p - количество единичных сдвигов (p - в процедуре);

    b - переменная для хранения первого или последнего элемента массива.

    Алгоритм решения задачи:

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

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

    Далее идет описание одного шага внешнего цикла.

    Если сдвиг происходит влево, то на место первого элемента становится второй, на место второго - третий и так далее. При кольцевом сдвиге на место последнего должен стать первый. Так как на место очередного элемента записывается следующий за ним, то первый элемент затрется. Поэтому его надо сохранить отдельно до выполнения внутреннего цикла. Внутренний цикл выполняется до предпоследнего элемента включительно. На предпоследнем элементе на его место записывается последний. После внутреннего цикла на место последнего элемента записывается ранее сохраненный первый элемент.

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

    Программа на языке Паскаль:

    const N = 10;

    type

    arr = array[1..N] of integer;

    var

    a: arr;

    i,j: byte;

    q: integer;

    procedure shift(var m: arr; p: integer);

    var b: integer;

    begin

    if p < 0 then

    for j:=1 to abs(p) do begin

    b := m[1];

    for i:=1 to N-1 do

    m[i] := m[i+1];

    m[N] := b;

    end

    else

    for j:=1 to p do begin

    b := m[N];

    for i:=N downto 2 do

    m[i] := m[i-1];

    m[1] := b;

    end;

    end;

    begin

    for i:=1 to N do begin

    a[i] := i;

    write(a[i],' ');

    end;

    writeln;

    readln(q);

    shift(a,q);

    for i:=1 to N do

    write(a[i],' ');

    writeln;

    end.

    Примеры выполнения программы:

    1 2 3 4 5 6 7 8 9 10

    -3

    4 5 6 7 8 9 10 1 2 3

    1 2 3 4 5 6 7 8 9 10

    4

    7 8 9 10 1 2 3 4 5 6

    Описанный выше алгоритм проще для понимания, но не является оптимальным. Существуют другие алгоритмы сдвига. Например:

    Надо сдвинуть влево на 3 элемента массив: 1 2 3 4 5 6 7 8
    Выделяем два подсписка: (1 2 3)(4 5 6 7 8)
    Переворачиваем списки: (3 2 1)(8 7 6 5 4).
    Переворачиваем весь массив: 4 5 6 7 8 1 2 3

    4. Реверс элементов массива паскаль

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

    Конечно, переставлять можно также, начиная с середины массива и двигаясь к его началу и концу. Однако вышеописанный способ немного проще.

    Если в массиве нечетное количество элементов, то в середине массива находится один элемент, у которого нет пары и который обменивать не надо. Если же в массиве четное количество элементов, то в середине находится пара, которая также должна обменяться. В любом случае количество обменов будет равно количеству элементов массива нацело деленному на 2.

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

    Pascal


    реверс массива паскаль
    const N = 10;


    var


    a: array[1..N] of integer;


    i: byte;


    b: integer;


    begin


    for i:=1 to N do


    read(a[i]);

    for i:=1 to N div 2 do begin


    b := a[i];


    a[i] := a[N-i+1];


    a[N-i+1] := b;


    end;

    for i:=1 to N do


    write(a[i],' ');

    writeln;


    end.


    5. Выбор элементов с заданными свойствами в другой массив

    Дан массив целых чисел из n элементов, заполненный случайным образом числами из промежутка [-80,150].
    1.Найти сумму четных элементов.
    2. Подсчитать количество элементов массива, значения которых состоят из двух цифр.
    3. Найти номер первого положительного элемента, делящегося на 5 с остатком 2
    4. В случае отсутствия искомых данных, вывести об этом сообщение.

    program Lab4;

    const n=10;

    var a:array[1..n] of integer;

        sum,k:integer;

        i:byte;

    begin

      randomize;

      writeln('Исходный массив');

      for i:=1 to n do begin

        a[i]:=-80+random(230);

        write(a[i]:5);

      end;

      writeln;

      for i:=1 to n do begin

        if (a[i]>=10) and (a[i]<100) or (a[i]<=-10) and (a[i]>-100) then inc(k);

        if (a[i]>0) and (a[i] mod 2 =0) then sum:=sum+a[i];

      end;

      for i:=1 to n do

        if a[i]>0 then

          if a[i] mod 5 = 2 then begin

            writeln('Номер первого положительного числа делящегося на 5 с остатком 2 = ',i);

            break;

          end;

      writeln('Сумма=',sum);

      writeln('Колличество 2-ух значных чисел ',k);

      readln

    end.

    6. Сортировка элементов массива: «пузырьковая» сортировка

    Алгоритм: Берем элемент массива, сравниваем со следующим, если наш элемент, больше следующего элемента, то мы их меняем местами. После прохождения всего массива, мы можем быть уверены, что максимальный элемент будет "вытолкнут" - и стоять самым последним. Таким образом, один элемент у нас уже точно стоит на своём месте. Т.к. нам надо их все расположить на свои места, следовательно, мы должны повторить данную операцию, столько раз, сколько у нас элементов массива минус 1. Последний элемент встанет автоматически, если остальные стоят на своих местах.

    Вернемся к нашему массиву :3 1 4 2
    Берем первый элемент "3" сравниваем со следующим "1". Т.к. "3" > "1", то меняем местами:
    1 3 4 2
    Теперь сравниваем "3" и "4", тройка не больше четвёрки, значит ничего не делаем. Далее, сравниваем "4" и "2". Четыре больше, чем два - значит меняем местами: 1 3 2 4 . Цикл закончился. Значит самый большой элемент уже должен стоять на своём месте!! Видим, что у нас так и произошло. Где бы "4" (наш самый большой элемент) не находился - он всё равно, после прохождения циклом всего массива, будет последним. Аналогия - как пузырёк воздуха всплывает в воде - так и наш элемент, всплывает в массиве. Поэтому и алгоритм, называется "Пузырьковая сортировка". Чтобы расположить следующий элемент, необходимо, начать цикл сначала, но последний элемент можно уже не рассматривать, потому что он стоит на своём месте.


    Сравниваем "1" и "3" - ничего не меняем.
    Сравниваем "3" и "2" - Три больше двух, значит меняем местами. Получается :1 2 3 4 . Второй цикл закончили. Мы сделали уже два цикла - значит, с уверенностью можно сказать, что у нас, два последних элемента уже отсортированы. Осталось нам отсортировать третий элемент, а четвёртый, встанет в нужное место, автоматически. Ещё раз, сравниваем первый элемент и второй - видим, что у нас уже всё на своих местах, значит, массив, можно считать, отсортированный по возрастанию элементов.

    Теперь осталось запрограммировать данный алгоритм на языке Pascal.

    const n = 4; {Заводим константу, это будет длина массива}

    var i, j, k :integer;

    m:array[1..n] of integer; {Заводим массив}

    begin

    {Будем запрашивать массив с клавиатуры:}

    Writeln('Введите массив:');

    for i:=1 to n do begin

    Writeln(i, ' элемент:');

    Readln(m[i]);

    end;

    {Внешний цикл отвечает за то, что мы должны повторить

    внутренний цикл столько раз, сколько у нас элементов

    массива минус 1.}

    for i:=1 to n-1 do begin

    {Внутренний цикл уже перебирает элементы и сравнивает между собой.}

    for j:=1 to n-i do begin

    {Если элемент, больше следующего, то меняем местами.}

    if m[j]>m[j+1] then begin

    k:=m[j];

    m[j]:=m[j+1];

    m[j+1]:=k;

    end;

    end;

    end;

    {Выводи результат:}

    for i:=1 to n do

    Write(m[i], ' ');

    end.

    Сортировка выбором

    Требуется отсортировать массив по возрастанию методом сортировки выбором.

    Для этого можно воспользоваться следующим алгоритмом.

    Найти максимальный элемент (max) в массиве (arr).

    Поместить его на последнее место (j).

    Элемент, находившийся в конце массива переместить на место, где прежде находился max.

    Уменьшить просматриваемую область массива на единицу (j – 1).

    Снова найти максимальный элемент в оставшейся области.

    Поместить его в конец просматриваемой области массива.

    и так далее.
    Программа на языке Паскаль:

    const n = 10;

    var

    arr: array[1..n] of byte;

    max, id_max, i, j: byte;

    begin

    randomize;

    for i := 1 to n do begin

    arr[i] := random(256);

    write(arr[i]:4)

    end;

    writeln;

    j := n;

    while j > 1 do begin

    max := arr[1];

    id_max := 1;

    for i := 2 to j do

    if arr[i] > max then begin

    max := arr[i];

    id_max := i

    end;

    arr[id_max] := arr[j];

    arr[j] := max;

    j := j - 1

    end;

    for i := 1 to n do

    write(arr[i]:4);

    end.

    7. Двумерные массивы. Работа с диагоналями

    Двумерные массивы Паскаля – матрицы

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

    Рассмотрим двумерный массив Паскаля размерностью 3*3, то есть в ней будет три строки, а в каждой строке по три элемента:



    Каждый элемент имеет свой номер, как у одномерных массивов, но сейчас номер уже состоит из двух чисел – номера строки, в которой находится элемент, и номера столбца. Таким образом, номер элемента определяется пересечением строки и столбца. Например, a 21 – это элемент, стоящий во второй строке и в первом столбце.

    Описание двумерного массива Паскаля.

    Существует несколько способов объявления двумерного массива Паскаля.

    Мы уже умеем описывать одномерные массивы, элементы которых могут иметь любой тип, а, следовательно, и сами элементы могут быть массивами. Рассмотрим следующее описание типов и переменных:

    Пример описания двумерного массива Паскаля

    Type
    Vector = array [1..5] of <тип_элементов>;
    Matrix= array [1..10] of vector;
    Var m: matrix;

    Мы объявили двумерный массив Паскаля m, состоящий из 10 строк, в каждой из которых 5 столбцов. При этом к каждой i -й строке можно обращаться m [ i ], а каждому j -му элементу внутри i -й строки – m [ i , j ].

    Определение типов для двумерных массивов Паскаля можно задавать и в одной строке:

    Type
    Matrix= array [1..5] of array [1..10] of < тип элементов >;
    или еще проще:
    type
    matrix = array [1..5, 1..10] of <тип элементов>;

    Обращение к элементам двумерного массива имеет вид: M [ i , j ]. Это означает, что мы хотим получить элемент, расположенный в i -й строке и j -м столбце. Тут главное не перепутать строки со столбцами, а то мы можем снова получить обращение к несуществующему элементу. Например, обращение к элементу M [10, 5] имеет правильную форму записи, но может вызвать ошибку в работе программы.

    Основные действия с двумерными массивами Паскаля

    Все, что было сказано об основных действиях с одномерными массивами, справедливо и для матриц. Единственное действие, которое можно осуществить над однотипными матрицами целиком – это присваивание. Т.е., если в программе у нас описаны две матрицы одного типа, например,

    type
    matrix= array [1..5, 1..10] of integer;
    var
       a , b : matrix ;

    то в ходе выполнения программы можно присвоить матрице a значение матрицы b ( a := b ). Все остальные действия выполняются поэлементно, при этом над элементами можно выполнять все допустимые операции, которые определены для типа данных элементов массива. Это означает, что если массив состоит из целых чисел, то над его элементами можно выполнять операции, определенные для целых чисел, если же массив состоит из символов, то к ним применимы операции, определенные для работы с символами.

    Ввод двумерного массива Паскаля.

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

    Рассмотрим пример ввода двумерного массива Паскаля с клавиатуры:

    Пример программы ввода двумерного массива Паскаля с клавиатуры

    type
       matrix= array [1..5, 1..10] of integer;
    var
       a, : matrix;
       i, j: integer; { индексы массива }
    begin
       for i :=1 to 5 do {цикл для перебора всех строк}
          for j :=1 to 10 do {перебор всех элементов строки по столбцам}
             readln ( a [ i , j ]); {ввод с клавиатуры элемента, стоящего в i -й строке и j -м столбце}

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

    Вывод двумерного массива Паскаля на экран.

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

    Пример программы вывода двумерного массива Паскаля

    for i :=1 to 5 do {цикл для перебора всех строк}
    begin
       for j :=1 to 10 do {перебор всех элементов строки по столбцам}
          write ( a [ i , j ]:4); {печать элементов, стоящих в i -й строке матрицы в одной экранной строке, при этом для вывода каждого элемента отводится 4 позиции}
       writeln ; {прежде, чем сменить номер строки в матрице, нужно перевести курсор на начало новой экранной строки}
    end ;

    Замечание (это важно!): очень часто в программах студентов встречается ошибка, когда ввод с клавиатуры или вывод на экран массива пытаются осуществить следующим образом: readln (a), writeln (a), где а – это переменная типа массив. При этом их удивляет сообщение компилятора, что переменную этого типа невозможно считать или напечатать. Может быть, вы поймете, почему этого сделать нельзя, если представите N кружек, стоящих в ряд, а у вас в руках, например, чайник с водой. Можете вы по команде «налей воду» наполнить сразу все кружки? Как бы вы ни старались, но в каждую кружку придется наливать отдельно. Заполнение и вывод на экран элементов массива также должно осуществляться последовательно и поэлементно, т.к. в памяти ЭВМ элементы массива располагаются в последовательных ячейках.

    Представление двумерного массива Паскаля в памяти

    Элементы абстрактного массива в памяти машины физически располагаются последовательно, согласно описанию. При этом каждый элемент занимает в памяти количество байт, соответствующее его размеру. Например, если массив состоит из элементов типа integer , то каждый элемент будет занимать по два байта. А весь массив займет S^2 байта, где S – количество элементов в массиве.

    А сколько места займет массив, состоящий из массивов, т.е. матрица? Очевидно: S i^S j , где S i - количество строк, а S j – количество элементов в каждой строке. Например, для массива типа

    Matrix = array [1..3, 1..2] of integer ;

    потребуется 12 байт памяти.

    Как будут располагаться в памяти элементы этого массива? Рассмотрим схему размещения массива M типа matrix в памяти.



    Под каждый элемент M [i,j] типа integer выделяется две ячейки памяти. Размещение в памяти осуществляется «снизу вверх». Элементы размещаются в порядке изменения индекса, что соответствует схеме вложенных циклов: сначала размещается первая строка, затем вторая, третья... Внутри строки по порядку идут элементы: первый, второй и т.д.

    Как мы знаем, доступ к любой переменной возможен, только если известен адрес ячейки памяти, в которой хранится переменная. Конкретная память выделяется для переменной при загрузке программы, то есть устанавливается взаимное соответствие между переменной и адресом ячейки. Но если мы объявили переменную как массив, то программа «знает» адрес начала массива, то есть первого его элемента. Как же происходит доступ ко всем другим элементам массива? При реальном доступе к ячейке памяти, в которой хранится элемент двумерного массива, система вычисляет ее адрес по формуле:

    Addr + SizeElem * Cols *( I -1)+ SizeElem *( J -1),

    где Addr – фактический начальный адрес, по которому массив располагается в памяти; I , J – индексы элемента в двумерном массиве; SizeElem – размер элемента массива (например, два байта для элементов типа integer ); Cols – количество элементов в строке.

    Выражение SizeElem * Cols *( I -1)+ SizeElem *( J -1) называют смещением относительно начала массива.

    Сколько памяти выделяется для массива?

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

    Для работы программы память выделяется сегментами по 64 Кбайт каждый, причем как минимум один из них определяется как сегмент данных. Вот в этом-то сегменте и располагаются те данные, которые будет обрабатывать программа. Ни одна переменная программы не может располагаться более чем в одном сегменте. Поэтому, даже если в сегменте находится только одна переменная, описанная как массив, то она не сможет получить более чем 65536 байт. Но почти наверняка, кроме массива в сегменте данных будут описаны еще некоторые переменные, поэтому реальный объем памяти, который может быть выделен под массив, находится по формуле: 65536- S , где S – объем памяти, уже выделенный под другие переменные.

    Зачем нам это знать? Для того чтобы не удивляться, если при компиляции транслятор выдаст сообщение об ошибке объявления слишком длинного массива, когда в программе встретит описание (правильное с точки зрения синтаксиса):

    Type myArray= array [1..50000] of integer;

    Вы уже знаете, что, учитывая двухбайтовое представление целых чисел, реально можно объявить массив с количеством элементов равным 65536/2 –1=32767. И то лишь в том случае, если других переменных не будет. Двумерные массивы должны иметь еще меньшие границы индексов.

    Примеры решения задач с двумерными массивами Паскаля

    Задача: Найти произведение ненулевых элементов матрицы.

    Решение:

    Для решения данной задачи нам потребуются переменные: матрица, состоящая, например, из целочисленных элементов; P – произведение элементов, отличных от 0; I , J – индексы массива; N , M – количество строк и столбцов в матрице.

    Входными данными являются N , M – их значения введем с клавиатуры; матрица – ввод матрицы оформим в виде процедуры, заполнение матрицы осуществим случайным образом, т.е. с помощью функции random ().

    Выходными данными будет являться значение переменной P (произведение).

    Чтобы проверить правильность выполнения программы, необходимо вывести матрицу на экран, для этого оформим процедуру вывода матрицы.

    Ход решения задачи:

    обсудим сначала выполнение основной программы, реализацию процедур обговорим чуть позже:

    введем значения N и M ;

    Введем двумерный массив Паскаля, для этого обращаемся к процедуре vvod ( a ), где а – матрица;

    Напечатаем полученную матрицу, для этого обращаемся к процедуре print ( a );

    Присвоим начальное значение переменной P =1;

    Будем последовательно перебирать все строки I от 1-й до N -й, в каждой строке будем перебирать все столбцы J от 1-го до M -го, для каждого элемента матрицы будем проверять условие: если a ij ? 0, то произведение P будем домножать на элемент a ij ( P = P * a ij );

    Выведем на экран значение произведения ненулевых элементов матрицы – P ;

    А теперь поговорим о процедурах.

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

    Type
    Matrix=array [1..10, 1..10] of integer;
    ..............................
    procedure primer (a: matrix);
    ..............................

    Вернемся теперь к нашим процедурам.

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

    Procedure vvod ( var m : matrix );

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

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

    Procedure print ( m : matrix );

    И вновь для реализации вложенных циклов внутри процедуры нам потребуются счетчики, пусть они называются так же – k и h . Алгоритм вывода матрицы на экран был описан выше, воспользуемся этим описанием.

    Пример программы двумерного массива Паскаля

    Program proizvedenie;
    Type
       Matrix=array [1..10, 1..10] of integer;
    Var
       A: matrix;
       N, m, i, j: byte;
       P: integer;
    Procedure vvod (var m: matrix);
    Var k , h : byte ;
    Begin
       For i :=1 to n do {переменная n для процедуры является глобальной, а значит «известной»}
          For j :=1 to m do {переменная m для процедуры является глобальной, а значит «известной»}
             M[i,j]:= random(10);
    End;
    Procedure print (m: matrix);
    Var k, h: byte;
    Begin
       For i:=1 to n do
       begin
          For j:=1 to m do
             Write (M[i, j]: 4);
          Writeln;
       end ;
    End ;
    Begin {начало основной программы}
       Writeln ('Введите размерность матрицы:');
       Readln(N, M);
       Vvod(a);
       Print(a);
       P:=1;
       For i:=1 to N do
          For j:=1 to M do
             If a[i, j]<>0 then p:=p*a[i, j];
       Writeln ( p );
    End .

    8. Двумерные массивы. Перестановка строк и столбцов

    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

    var a: array [1..100, 1..100] of integer;

    n, k1, k2, j, i, x: integer;

    begin

    writeln('Введите размер массива <100');

    read (n);

    for i:=1 to n do

    begin

    for j:=1 to n do

    begin

    a[i,j]:=random(101);

    write(a[i,j], ' ');

    end;

    writeln;

    end;

    writeln('Введите номер строк, которые нужно поменять местами');

    read(k1, k2);

    for j:=1 to n do

    begin

    x := a[k1, j];

    a[k1, j] := a[k2, j];

    a[k2, j] := x;

    end;

    writeln;

    for i:=1 to n do

    begin

    for j:=1 to n do

    write(a[i,j], ' ');

    writeln;

    end;

    end.

    Работа с цифрами числа. Определение, является ли число простым числом или палиндромом

    uses crt;

    var a,b,c:longint;

    begin

    clrscr;

    write('Введите целое положительное число a=');

    readln(a);

    b:=a;

    c:=0;

    while b>0 do

     begin

      c:=c*10+(b mod 10);

      b:=b div 10;

     end;

    writeln(c);

    if c=a then write('Палиндром')

    else  write('Не палиндром');

    readln

    end.


    написать администратору сайта