FoxWeb

софт для студентов
Искать здесь

Методика решения задач с одномерными массивами

Раздел: Turbo Pascal Автор: fox++
E-mail: спаму - нет! Www: http://foxweb.net.ru
Просмотров: 9068 Дата: 16.01.2005
Рассматриваются такие вопросы, как заполнение массива, вывод массива на экран, поиск по условию, создание нового массива.

Почему вдруг я захотел написать эту статью? А потому что 80% всех часто задаваемых вопросов по алгоритмам связано с массивами. Ну например, как вывести на экран все отрицательные числа массива? Или найти третий нулевой элемент массива. А ещё заменить первый чётный элемент последним нечётным. Таких задач бесконечное множество, однако методы их решения стандартны. Программирование давно превратилось из искусства в ремесло. Потому и надо искать знакомые методы, а не изобретать велосипед. Ну вот, вроде с введением всё.

Что такое одномерный массив

Для начала вспомним, что есть одномерный массив. Массивы представляют собой ограниченную упорядоченную совокупность однотипных величин. Каждая отдельная величина называется элементом массива. Тип элементов может быть любым, принятым в языке ПАСКАЛЬ, кроме файлового типа. Тип элемента называется базовым типом. Вся совокупность элементов определяется одним именем. Для обозначения отдельных элементов используется конструкция, называемая переменной с индексом или с индексами:

A[5] S[k+1] B[3,5]

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

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

изображение массива

У каждого ящика есть свой номер (индекс i). В каждом ящике хранится некоторое значение (элемент A[i]). Тогда для массива, изображённого на рисунке, справедливо следующее:

A[1]:=4;
A[2]:=5;
A[3]:=6;
A[4]:=3;
A[5]:=0;

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

Обращение к элементам массива

Попробуем теперь обратиться к некоторым элементам массива. Например выведем на экран третий элемент. Его переменная будет выглядеть A[3].

i:=3;
WriteLn (A[i]);

или

WriteLn (A[3]);

или

z:=A[3];
WriteLn (z);

Первый способ более универсален, поскольку i - индекс элемента - может изменяться где-то в другом месте программы. Во втором случае мы печатаем строго третий элемент, что и требовалось. В третьем случае мы вводим новую переменную z, равную A[3], чтобы в других местах программы ещё несколько раз обращаться к A[3] через z.

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

Заполнение массива по формуле

Обычно задачи про одномерные массивы начинаются со слов "заполните массив..." или "дан одномерный массив..." - всё это предполагает то, что массив был ранее создан и заполнен.

Теперь нам ясно, что присвоить элементу массива значение можно следующим образом:

A[i]:=x;

Но если этих элементов десять или десять тысяч? Тогда на помощь приходит оператор цикла For-to-do. Приведу такой сэмпл:

For i:=1 to 10000 do
A[i]:=i*2;

Получим в каждом элементе массива число в два раза большее, чем его индекс. Это значит, что в первым элементом будет 2, а вторым - 20000. Конечно, вместо выражения i*2 можно использовать любые математические формулы. Тогда каждый раз массив будет заполняться по функциональной зависимости, где индекс - это аргумент функции (i), а сам элемент - значение функции (A[i]). Посмотрим массив значений функции y=x2 на промежутке [1; 20].

For x:=1 to 20 to
y[x]:=sqr(x);

Здесь видно, что в программе y[x]:=sqr(x) - это тоже самое, что и математическое выражение y(x)=x2. А задание к этой программке будет звучать примерно так: "Заполнить массив y квадратами чисел от 1 до 20".

Заполнение массива с клавиатуры

Но если задании сказано, что массив следует заполнить с клавиатуры? В основе заполнения массивов, как мы выяснили, лежит простое присваивание. Ну а там, где присваивание, есть и ввод с клавиатуры. Вспомним как это делается для обычных переменных:

ReadLn (x);

Теперь программа ожидает, пока мы наберём на клаве число и нажмём Enter. Всё! Наше число хранится в переменной x. Прикидываем, что элемент массива - это та же переменная, только с индексом:

ReadLn (A[i]);

В зависимости от индекса i введённое пользователем число запишется в массиве A по номеру i. Вспомним, как мы присваивали значения элементов в цикле:

For i:=1 to 20 do
ReadLn (A[i]);

Программа запрашиват числа одно за другим, пока мы не введём 20 чисел. И все они по окончании цикла будут находиться в массиве A по тем номерам и в том порядке, как мы их вводили. Параллельно с вводом с клавиатуры можно выводить на экран номер вводимого элемента, чтобы пользователь не запутался:

For i:=1 to 20 do
begin
Write ('A[',i,']=');
ReadLn (A[i]);
end;

Тогда на экране сначала покажется надпись A[1]= и рядом курсор ввода. Ну вот, теперь мы можем заполнять массивы с клавиатуры!

Заполнение массива случайными числами

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

Randomize; {запуск генератора случайных чисел}
For i:=1 to 20 do
A[i]:=Random(100);

Тогда мы получим массив, заполненный разными числами от 0 до 99 благодаря функции Random. Если умело использовать её, то можно заполнить массив не только от 0 до 99, но и от -100 до 100. Для этого сгенерируем случайное число Random(201) (это будет от 0 до 200) и отнимем 100. Тогда, если получится 0, отнимается 100 и получаем
-100. Если генерируется 200, опять отнимается 100 и получаем 100. Тут в общем-то всё просто, если в школе учили алгебру и знаете определение "область принимаемых значений".

Randomize; {запуск генератора случайных чисел}
For i:=1 to 20 do
A[i]:=Random(201)-100;

Теперь мы умеем заполнять массив тремя способами. Этого хватит для решения задач любой сложности. Ведь главное в программе - это исходные данные, полученные извне.

Вывод массива на экран

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

Итак, вывод на экран значения элемента массива - это очень просто:

WriteLn (A[1]);
WriteLn (A[2]);
- - - - - - - -
Writeln (A[n]);

Главное помнить, что в случае с WriteLn добавляется перевод строки и следующий вывод печатается на новой строке. С Write весь вывод идёт в одну строку без пробелов! Потому-то пробел и добавляют "искуственно" с помощью Write (' ').

Теперь же рассмотрим, как элементы массива можно вывести в цикле. Это аналогично алгоритму заполнения с клавиатуры, только мы не вводим, а выводим значения. Следующий сэмпл демонстрирует самый простой вывод массива в столбец (обратите внимание на WriteLn, который переводит строку):

For i:=1 to 20 do
WriteLn (A[i]);

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

For i:=1 to 20 do
begin
Write (A[i]);
Write (' ');
end;

Или так, что проще:

For i:=1 to 20 do
begin
Write (A[i],' ');
end;

А теперь самый сложный способ - форматированный вывод. Он используется с многозначными дробными числами и пригоден для вывода больших массивов в виде таблиц.

For i:=1 to 20 do
WriteLn (A[i]:4:2); {4 и 2 - в целой и дробной части числа}

Поиск в массиве по заданному условию

Для начала следует вспомнить, что условие выражается с помощью оператора If. Потом надо сесть и хорошо подумать - какое условие следует вычислить? Рассмотрим простейшее условие вывода на экран.

Допустим задание звучит так: "вывести на экран элементы, равные нулю". Это очень просто. Для каждого элемента массива в цикле вычисляется следующее условие:

If A[i]:=0 then WriteLn (A[i]);

Условие читается так: "Если элемент A[i] равен нулю, то выводим на экран значение A[i]". Итак, сэмпл программы, который выводит на экран нулевые элементы, будет выглядеть так:

For i:=1 to 20 do
If A[i]:=0 then WriteLn (A[i]);

Счётчики

Допустим нам необходимо не только вывести на экран нулевые элементы, но и подсчитать их количество. Как это сделать? Это делается с помощью такого же условия, но для подсчёта мы вводим новую переменную. Пусть это будет переменная целого типа z:integer. Тогда каждый раз при выполнении условия к ней будет прибавляться единица. В этом и заключается принцип счётчика.

For i:=1 to 20 do
If A[i]:=0 then
begin
WriteLn (A[i]);
z:=z+1;
end;

Как только очередной элемент равен нулю, он выводится на экран оператором WriteLn, после чего к счётчику z прибавляется 1.

Создание нового массива из элементов исходного массива

Иногда в задании указывается, что из определённых элементов массива нужно составить новый массив. Пусть это будет массив B[20].

Прежде, чем приступить к написанию программы, посмотрим как это можно сделать вручную. Чтобы заполнять поочерёдно все элементы массива B при перечислении массива A, необходимо установить счётчик индекса для массива B (пусть это будет n:=1). Когда будет обнаружен первый ноль, он будет записан в B[n], после чего n:=n+1. Следующий ноль будет записан в B[2] и так далее.

  1. Вначале n:=1.
  2. Берём i:=1 элемент массива A.
  3. Сравниваем его с нулём.
  4. Если он равен нулю, то присваиваем его B[n].
  5. Увеличиваем n на единицу.
  6. Цикл повторяется.

Теперь, когда алгоритм ясен, составим сэмпл. Вообще, в этой программе z и n равны, так как они обе показывают число нулей.

For i:=1 to 20 do
If A[i]:=0 then
begin
WriteLn (A[i]);
z:=z+1;
B[n]:=A[i];
n:=n+1;
end;

Кстати, вместо конструкции n:=n+1 можно использовать стандартную функцию инкремента (приращения переменной) inc(n). Вместо кнструкции n:=n+x можно применить inc(n,x).

Подведём итоги

От начала до конца я рассматривал такую задачу:

Дан массив целых чисел A, состоящий из 20 элементов. Определить число нулевых элементов и записать их в массив B.

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

Program Null;
var
   i,n:integer;
   A,B:array [1..20] of integer;

begin

For i:=1 to 20 do
begin
   Write ('A[',i,']=');
   ReadLn (A[i]);
end;

n:=1;

For i:=1 to 20 do
   If A[i]:=0 then
   begin
      WriteLn (A[i]);
      n:=n+1;
      B[n]:=A[i];
   end;

WriteLn ('В массиве найдено ',n,'нулей.');
ReadKey;

end.

Комментарии

Atrinax 27.10.2007 07:20:58 #
супер спс огромное — написано с юморком без которого было бы всё это дело чрезвычайно скучным =)
просрал пару информатику — так что пришлось в инете прям на уроке повышать уровень знаний =)
~Luc1fer~ 23.11.2007 23:38:33 #
ЗачОт! =)
Диана 03.02.2008 11:40:28 #
как же это всё сложно... но так хочется пять по информатике...ну ничче нагоню...
Лёлик 26.02.2008 22:49:28 #
Я в курсовую это применил... препод балдел не поверил что я "делал"...а тебе от меня поклон до земли...
Ванёк 20.04.2008 21:42:44 #
а есть задачи по массивам?Просто мне дали работу найти в Инету задачи на массивы на олимпиаду училке!!!
foxweb 21.04.2008 10:44:08 #
Вот список задач: http://foxweb.net.ru/texts/18.htm
Kolian 19.05.2008 14:00:29 #
Спасибо!А то я рисковал 3 за четверть получить(я в 8 классе)
олька 26.05.2008 21:05:48 #
а я ничего не поняла, хотя на носу экзамен
азамат 30.05.2008 13:13:43 #
"Как мы знаем, вывод на экран осуществляется оператором Writeln (). Если вы об этом слышите впервые, то можете выключить компьютер и идти спать :)."
Вот эта фраза меня особенно развеселила, МОЛОДЕЦ.

Оставить комментарий

Ваше имя

Ваш комментарий

Код   Защитный код. Если вы не видите здесь рисунок - обновите страницу.
Оценка   

Заметки по этой теме