Как можно было бы сделать, если использовать массив?

1. Ввести значения и заполнить ими массив.

2. Отыскать среднее значение в массиве.

Var

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

s: integer;

i:byte;

begin

s:=0;

for i:=1 to 10 do

begin

wtite(‘введите —’);

readln(a[i]);

s:=s+a[i];

end;

end.

16.Правила разработки цикла

Известно по крайней мере два класса задач, каковые приводят к появлению цикла:

  • обработка либо формирование массивов — при переносе формулировки задачи типа

//типа

либо

//типа инициализировать/ввести массив

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

  • итерационные методы – методы, основанные на применении рекуррентных формул. При ответе задач этого (второго) класса циклы разрабатываются снизу-вверх. Рекуррентные формулы в большинстве случаев употребляются по причине того, что для понижения сложности вычислений (замена умножения — сложением, а возведения в степень — умножением и т.п.) на каждом шаге при каждом новом повторении цикла любой новый итог получается с применением ветхого (ранее взятого) результата. Возможно выделить 2 разновидности итерационных методов:

1. Методы, которые связаны с реализацией т.н. n-арных операций:

S = Как можно было бы сделать, если использовать массив? =x1+x2+x3+…+xn S = Как можно было бы сделать, если использовать массив? = x1•x2•x3•…•xn S = X!=1•2•3•4•…•X и т.п.

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

2. Методы приближенных вычислений — методы, разрабатываемые для постепенного (пошагового) приближенного нахождения ответа задач (к примеру, поиск корня уравнения), для которых неизвестно, как отыскать правильное ответ.

Обе задачи второго класса приводят к появлению циклов, каковые разрабатываются способом снизу вверх. Наряду с этим первая разновидность задач второго класса реализуется посредством циклов с известным числом повторений (цикла for — для каждой n-арной операции, зная n, возможно выяснить число повторений), а вторая разновидность — посредством циклов с малоизвестным числом повторений.

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

В большинстве случаев, очередное повторение тела цикла строится с применением результата, взятого при прошлом повторении тела цикла, наприемр, как в этом случае

xi = xi-1 + h

yi = f(xi).

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

Но, в случае, если цикл организован так, что очередное повторение тела цикла не применяет итог прошлого повторения, как в этом случае

xi = (i-1)*h и yi = f(xi)

то в этом случае подготовка цикла не нужна.

Порядок разработки циклов восходящим способом:

1. Записываем линейный метод (в котором, к примеру, многоместная операция реализуется посредством последовательности громадного количества двоичных операций).

2. Находим рекуррентную формулу (подмечаем повторяемость) для определенной последовательности шагов.

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

4. В случае, если подготовка цикла не несложная, то нужно выполнить ее упрощение.

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

6. Нужно выполнить операцию отбрасывания лишних индексов.

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

При появлении команд:

Организовать массив

либо

Обработать массив

Как можно было бы сделать, если использовать массив? Пример:

ввести массив

либо

вывести массив не связано с накоплением и вычислением значений

либо

присвоить массив массиву

Как можно было бы сделать, если использовать массив? Но не:

Отыскать сумму элементов массива связано с накоплением

Отыскать минимальный либо большой элемент массива значений

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

В следствии получается много формулировок команд следующего вида:

обработать первую компоненту

Как можно было бы сделать, если использовать массив? обработка массива обработать вторую компоненту

………………………………………………..

обработать n-ую компоненту

уточнение

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

1. Сходу возможно записать тело цикла, имеющее одну из следующих 2 форм:

организовать i-ю компоненту либо обработать i-ю компоненту

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

К примеру:

For i := to do …

где i – параметр цикла.

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

— Отыскать сумму элементов массива

— Отыскать минимальный либо большой элемент массива

и т.п.

Действия над массивами

15.6.1 Возможно присваивать содержимое одного массива второму, но не всегда.

Type

t = array [1..10] of byte;

Var

a, b: array [1..10] of byte;

c: array [1..10] of byte

e, f: t;

Верно

begin

a := направляться;

e := f;

Неправильно

a := c;

e := a;

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

Тип С неэквивалентен типам А и В. Если бы необходимо было сделать тип С эквивалентным типам А и В, то необходимо:

a, b, c: array [1..10] of byte;

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

if a = b then … — запрещено.

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

15.6.2 Инициализация массивов.

Замечание: в отличие от языка Си, где имеется старт языка т в соответствии с этому стандарту все глобальные переменные, а также массивы, в начале исполнения программы инициализируются нулями, для Паскаля (Турбо-Паскаля) нет стандарта (данный язык — внутренняя разработка компании Борланд) и массивы (в зависимости от реализации) смогут не инициализироваться (инициализироваться всяким мусором — не обязаны инициализироваться непременно 0). Исходя из этого для определенности нужно перед применением массивов задать им начальное значение. Для этого имеется три пути:

1. Применение типизированных констант (уже разглядели выше)

2. Как можно было бы сделать, если использовать массив? Как можно было бы сделать, если использовать массив? Применение цикла (по элементам)

3. Как можно было бы сделать, если использовать массив? Применение специальной функции Fillchar().

Применение цикла (по элементам)

Как можно было бы сделать, если использовать массив? Var

a: array [1..5] of byte;

i: byte;

begin

randomize;

for i := 1 to 5 do

a[i] := i; // элементы массива инициализируются значениями параметра цикла

либо

a[i] := random(100); // элементы массива инициализируются псевдослучайными числами

либо

begin write(‘a[‘, i, ‘] = ‘); readln(a[i]) end;

// элементы массива инициализируются в диалоге с пользователем

Как можно было бы сделать, если использовать массив?

Применение процедуры Fillchar(): типа char

Fillchar(имя массива, число байт (не элементов), значение) — заполняет побайтно всю область памяти под массив заданным значением {fillchar (a, 5 ,#0);}, причём проверка на выход за границы массива не выполняется.

Пользоваться данной процедурой нужно бережно: в случае, если тип элемента массива будет не byte, а integer, то fillchar (a,5,#1) забьет массив значением 257, а не 1. Помимо этого, если бы тип элементов был integer, нужно было бы писать 5*sizeof(integer) вместо 5.

15.6.3 Элементы массива возможно применять везде, где возможно применять простые скалярные переменные (в процедурах ввода и операторах присваивания-вывода и т.п.)

15.6.4 Обмен значениями между подмассивами и между массивом и подмассивами

15.6.4.1 Обмен между подмассивами

Подмассив – часть массива, к которой возможно обратиться, применяя число индексов, меньшее чем число размерностей массива. Более неспециализированное наименование подмассива – сечение. В языке PL/I: А(1,*) – 1-я строчок, А(*,1) – 1-я колонка массива. В Паскале сечения вероятны лишь для строчков: A[1] – первая строчок n-мерного массива.

Правило (выше было дано): тип элемента массива определяется тем, сколько индексов указано по окончании имени массива.

Разглядим пример:

Const N=3;

Var

A: array[1..2, 1..N] of byte;

B: array[1..2, 1..N] of byte;

Как можно было бы сделать, если использовать массив? Begin возможно применять sizeof(тип элемента)*число_ячеек

Fillchar(a, sizeof(a) div 2, 1); ————- заполнение 1-ой строки единицами (верно)

Fillchar(a[2,1], sizeof(a) div 2, 2); ————- заполнение 2-ой строки двойками (неправильно)

Как можно было бы сделать, если использовать массив?

возможно и без того: round(sizeof(a)/2) — в отличие от DIV деление посредством ‘/’ постоянно даёт вещественный итог

Замечание. Так показывать параметр fillchar запрещено (и указатель применять также запрещено)

Нужно (возможно) один из двух вариантов:

1) Fillchar(a, sizeof(a), 2); //целый массив а заполняем двойками

Fillchar(а, sizeof(a) div 2, 0); //первую строчок очищаем от двоек

2) Fillchar(a[2], sizeof(a) div 2, 2); //вторую строкузаполняем двойками

a[1] := a[2]; ——— возможно ——- обмен между 1 и 2 строчками одного массива

Как можно было бы сделать, если использовать массив? b[1] := a[2]; ——— запрещено (типы не эквивалентны)

Правило: Обмениваться смогут подмассивы лишь эквивалентных типов.

Но это правило возможно обойти следующим образом. Пускай нужно b[1] := a[2].

Move( a[2], — 1 довод (откуда брать)

b[1], — 2 довод (куда помещать)

sizeof(a) div 2); — 3 довод (какое количество переслать байтов)

Эта процедура байты из одного места в памяти в второе (диагностику типа этих байтов она не делает).

15.6.4.2 Обмен между подмассивом и массивом

Разглядим сходу Пример:

Type

t=array[1..3] of byte;

Var

A: array[1..2, 1..3] of byte;

B: t;

C: array[1..2] of t;

Как можно было бы сделать, если использовать массив? Begin тип A[2] = array[1..3] of byte (? t)

A[2] := b; ————————- запрещено (типы не эквивалентны)

тип b = t

C[2] := b; ————————- возможно (тип c[2] = t = тип b)

Move(b, a[2], sizeof(b)); ——- возможно

B := a[2]; ————————— запрещено

B := t(a[2]); ————————— возможно

Move(a[2], b, sizeof(b)); ——- возможно

B := c[2]; ——————— возможно

15.6.5 Сдвиг значений в массива

15.6.5.1 Сдвиг элементов одномерного массива вправо

Задача: нужно выполнить сдвиг заданной части массива M (начиная с позиции i1 (пускай i1=3) и заканчивая позицией i2 (пускай i2=7) на заданное число позиций вправо (пускай = 2).

Изображение постановки задачи имеет форму:

Var M: array[1..11] of byte; Используем разработку цикла восходящим

m[9]:=m[7] m[8]:=m[6] m[7]:=m[5] m[6]:=m[4] m[5]:=m[3] i j Обобщенная запись: M[i] := M[j] = M[a*i+b]

Как можно было бы сделать, если использовать массив? i1 i2 i значительно уменьшается способом и возьмём следующий линейный

метод:

Mj
Mi

Массив одномерный и для прохода по нему достаточно одного индекса – i (а у нас в обобщенной записи – два индекса). Дабы избавиться от второго индекса (j), нужно в общем случае выразить зависимость j от i. В общем виде эта зависимость линейная (возможно по точкам выстроить зависимость j от i для проверки) и имеет форму: j := a*i + b

Для нахождения a и b нужно составить совокупность уравнений (из линейного метода):

7 = a*9 + b

6 = a*8 + b

j i

Сейчас возможно записать цикл. НО:

Запрещено

(глядя на рисунок выше написать)

Как можно было бы сделать, если использовать массив? i1 + i3 i2 + i3-1

For i:= 5 to 9 do

M[i] := M[i-2];

Тут новые значения преждевременно

будут затирать ветхие

Нужно число байт

For i:=9 downto 5 do m[i] := m[i-2]; т.е. двигаться по массиву при сдвиге вправо нужно в направлении, противоположном направлению сдвига, т.е. влево. Move[a[5], a[3], 5); // сдвиг влево Move[a[3], a[5], 5); // сдвиг вправо для произвольного типа нужно писать так: (i2 – i1 + 1) * (sizeof(тип элемента)) число пересылаемых число байт на один элемент элементов
Процедура Move в любой момент верно выполняется (она сама в верном порядке расставляет операторы присваивания)

Самостоятельно: разобрать сдвиг массива влево.

15.6.6 Поиск элемента (одномерного ) массива

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

Поиск

Как можно было бы сделать, если использовать массив?

Как можно было бы сделать, если использовать массив?
label уходим; Const L=1; H=10; Var A: array[L..не of integer; эталон: integer; Итог: Longint; Нашли: Boolean; Середина, Низ, Верх: Longint; //текущие границы промежутка Begin Низ := L; {левая граница промежутка} Верх := H; {правая граница промежутка } Нашли := FALSE; {показатель того, что нашли} Середина:= 0; {индекс середины промежутка между Верх и Низ} Итог := 0; {индекс искомого элемента} эталон := ….; {то, что ищем} {Проверка — имеется ли искомый эталон в массиве?} IF (A[Низ] эталон) OR (A[Верх] эталон) then begin writeln(‘Совпадение искать безтолку’); goto уходим; end; Repeat Середина := round((Верх+Низ)/2); IF A[Середина] эталон then Верх := Середина //эталон в левой половине else if A[Середина] эталон then Низ := Середина //эталон в правой половине else Нашли := TRUE; // значит A[Середина] = эталон until (Нашли=TRUE) OR (Низ = Верх)) IF Нашли = TRUE then Итог := Середина {в Итог — индекс искомого элемента} else writeln(«Совпадений не отыскано.») уходим:; end.

В начале бинарного поиска имеем 2 обстановке:

Обстановка Воздействие
Как можно было бы сделать, если использовать массив? Эталон в массиве имеется Отыскать
Эталона в массиве нет (A[Низ] эталон) OR (A[Верх] эталон) Сообщение

цикл, где на каждом повторе вычисляем новую

Как можно было бы сделать, если использовать массив? середину и разбираем 3 обстановке:

Обстановка Воздействие
Эталон в левой половине (A[Середина] эталон) Верх := Середина
Эталон в правой половине (A[Середина] эталон) Низ := Середина
Как можно было бы сделать, если использовать массив? Эталон ровно в середине (A[Середина] = эталон) Нашли := True Итог := Середина

выход из цикла := ((Нашли = True) OR

(Низ = Верх))

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

Как можно было бы сделать, если использовать массив? см. Однопроходные методы (индуктивные функции) в Кушниренко, Лебедев «Программирование для математиков»

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

К примеру: выбрать из всех студентов лишь мужского пола ростом выше 1.8м и не старше 20 лет.

Тут возможно записать обобщенный критерий поиска в виде логического выражения

П1 и П2 и П3

Пол = мужской рост = 180 см возраст

Задача поиска сводится к однократному проходу по отбору и массиву на протяжении прохода тех студентов, характеристики которых обращают приведенное логическое выражение в истину (TRUE):

Repeat

if (П1 and П2 and П3)

then отобрать

else искать дальше

перейти к следующему

until закончить

б) За пара проходов по массиву– в случае, если удовлетворение запроса связано с анализом и накоплением статистики.

К примеру: нужно выбрать из всех студентов лишь 3 студентов моложе 20 лет и ростом не ниже 180см каковые значительно чаще звонят (пишут) мне по окончании 22:00.

Слово чащев условии показывает, что нужно накопить статистику перед выбором.

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

— критерий, по которому отбирается (накапливается) статистика;

— критерий отбора из того, что накопили.

Критерий для накопления статистики (какое количество раз звонил) обязан включать показатели:

— информация о поле студента;

— информация о возрасте студента;

— информация о росте студента;

— информация о времени звонка студента

и будет иметь вид, подобный рассмотренному выше

П1 и П2 и П3 и П4

Пол = мужской рост = 180 см возраст = 22

Решить поставленную задачу возможно по крайней мере так:

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

15.6.7 Сортировка элементов (одномерного) массива (для ускорения поиска в массиве)

Сортировка — размещение (переупорядочивание) элементов по определенному критерию. В большинстве случаев — по убыванию (descend) либо возрастанию (ascend). Существует довольно много способов сортировки. Несложный, но не самый нехороший (лучший) — сортировка выбором. Разглядим, как выполнить сортировку по убыванию. Для этого нужно:

— сперва последовательно разглядывать кандидатов на место самого первого элемента (самого громадного), по окончании чего громаднейший из кандидатов делается первым (обменивается с первым);

— после этого среди оставшихся (N-1) элементов массива последовательно рассматриваются кандидаты на место 2-го элемента и громаднейший из кандидатов при просмотре делается вторым (обменивается со вторым элементом);

— и т.д.

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

Введем обозначения:

i – индекс элемента, на место которого ищем кандидата

j – индекс элемента, что мы просматриваем в качестве кандидата

i=1 i=2 i=3 i=4 i=5

Как можно было бы сделать, если использовать массив? 1 3 4 2 5— Исходное состояние массива

3 1 4 2 5—-После итерации для j=2———-i = 1 j = 2

4 1 3 2 5—-После итерации для j=3———-i = 1 j = 3 i = 1

4 1 3 2 5—-После итерации для j=4———-i = 1 j = 4

Как можно было бы сделать, если использовать массив? 5 1 3 2 4—-После итерации для j=5———-i = 1 j = 5

——————————————————————

5 3 1 2 4—-После итерации для j=3———-i = 2 j = 3

5 3 1 2 4—-После итерации для j=4———-i = 2 j = 4 i = 2

Как можно было бы сделать, если использовать массив? 5 4 1 2 3—-После итерации для j=5———-i = 2 j = 5

——————————————————————

5 4 2 1 3—-После итерации для j=4———-i = 3 j = 4 i = 3

Как можно было бы сделать, если использовать массив? 5 4 3 1 2—-После итерации для j=5———-i = 3 j = 5

——————————————————————

5 4 3 2 1—- По окончании итерации для j=5———i = 4 j = 5 i = 4

Возможно подметить:

— при поиске каждого нового кандидата число просматриваемых элементов значительно уменьшается на единицу;

— при поиске кандидата на I-ое место I фиксируется, а J пробегает значения от I+1 до N.

Разумеется, что требуется два цикла:

— внешний по элементам, для которых ищем кандидата (цикл по параметру I, где I изменяется от 1 до N-1);

— внутренний по элементам-кандидатам (цикл по параметру J, где J изменяется от I+1 до N).

В итоге возьмём следующий фрагмент программы:

for i:= 1 to N-1 do

for j:=i+1 to N do

ему ищем замену

a[i]
a[j]

if ( a[j] a[i] ) // в случае, если кандидат больше по значению, чем текущий

кандидат

Как можно было бы сделать, если использовать массив? then

R

begin

1) R := a[i]; //дабы не утратить значение переменной a[i]

2) a[i] = a[j];

3) a[j] = R;

end;

Замечания: по поводу реализации массивов в Паскале:

1. Число размерностей массива ничем не ограничено, но размер массива как любой статической переменной в памяти ограничен 64 Кб (нельзя объявить тип размером 64 Кб).

2. Индексы смогут быть как хорошими, так и отрицательными.

3. Тип индексов возможно любым порядковым, не считая типа longint.

4. В Турбо-Паскале имеется два режима компиляции, имеющие отношение к массивам:

{$R+} и {$R-} — выполняется либо нет проверка, не выходит ли индекс за заявленные границы диапазона:

— в случае, если проверка выполняется, то при нарушении границ диапазона программа неудачно завершается с кодом 201 (Range Check Error);

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

Примечание:

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

{$R-}

Var a: array [1..1] of integer:

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

В случае, если по адресу а динамически выделить память, то возьмём массив для того чтобы размера, какого именно захотим (мы возвратимся к этому, в то время, когда будем разглядывать тему «Указатели»).

5. При передаче массивов как параметров в подпрограммы не рекомендуется определять тип массива конкретно в заголовке подпрограммы (из-за неосуществимости наряду с этим обеспечить эквивалентность типов фактического и формального параметров — массивов).

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

6. В качестве формального параметра подпрограммы возможно применять массив без границ (открытый массив).

Var

a: array of char;

Для работы с ними употребляются функции High (возвращает верхнюю границу индекса — в большинстве случаев = число элементов массива минус 1; не путать с Hi(x) для целый доводов) и Low (возвращает нижнюю границу индекса, в большинстве случаев = 0; не путать с Lo(x) для целых доводов).

Множества.

Уроки C# (C sharp) | #9 — Массивы


Интересные записи:

Понравилась статья? Поделиться с друзьями: