Programming Taskbook 0


Download 1.62 Mb.
Pdf ko'rish
bet59/71
Sana21.06.2023
Hajmi1.62 Mb.
#1644761
TuriУчебное пособие
1   ...   55   56   57   58   59   60   61   62   ...   71
Bog'liq
Abramyan-Pascal2016-1


Глава 5. Дополнительные средства обработки массивов 
97 
могли вместо оператора присваивания с функцией Copy использовать вари-
ант со срезом: 
b := a[:]; 
Важно понимать, что при описанных способах копирования выделяет-
ся дополнительная память для хранения копии. 
Копию можно создать без выделения памяти, если скопировать дан-
ные из одного массива (массива-источника) непосредственно в другой 
(массив-приемник). Для этого можно использовать процедуру (метод мас-
сива) CopyTo, вызов которой имеет вид src.CopyTo(dst, dstStart), где src опре-
деляет массив-источник (от англ. source), dst — массив-приемник (от англ. 
destination), а dstStart — индекс в массиве dst, начиная с которого в него бу-
дут записываться элементы массива src. Всегда копируются все элементы 
массива-источника; если для этого действия в массиве-приемнике недоста-
точно элементов, то будет возбуждено исключение.
Например, если массивы a и b инициализированы так же, как в преды-
дущем примере, то вызов a.CopyTo(b, 0) приведет к аварийному завершению 
программы, а вызов b.CopyTo(a, 0) выполнится успешно (в результате в a 
будут содержаться три элемента: 6, 7, 3). Успешно проработает и вызов 
b.CopyTo(a, 1); в этом случае в a будут содержаться элементы 1, 6, 7. 
С помощью метода CopyTo можно реализовать короткий и эффектив-
ный алгоритм объединения массивов, не использующий циклы. Предполо-
жим, что требуется объединить элементы массивов a и b (в указанном по-
рядке) в новом массиве res. Вначале надо выделить память для массива res 
(при этом его размер должен быть равен суммарному размеру исходных 
массивов), а затем вызвать процедуру CopyTo дважды: для копирования в 
нужные позиции массива res элементов массива a и b, например: 
var res := new integer[a.Length + b.Length]; 
a.CopyTo(res, 0); 
b.CopyTo(res, a.Length); 
В языке PascalABC.NET предусмотрен специальный вариант опера-
ции + для динамических массивов, позволяющий для формирования мас-
сива res использовать вместо указанных выше операторов единственный 
оператор:
var res := a + b; 
Операция a + b размещает в памяти массив и заполняет его нужным 
образом, после чего ссылка на эту область памяти записывается в пере-
менную res. Обратите внимание на то, что в данном случае тип массива res 
выводится из типов массивов a и b; необходимо лишь, чтобы типы масси-
вов a и b совпадали. 


98 
Проиллюстрируем применение рассмотренных возможностей, решив 
задачу Array57. В ней требуется записать в новый целочисленный массив 
b вначале все элементы исходного массива a с четными порядковыми но-
мерами (2, 4, 6, …), а затем — с нечетными (1, 3, 5, …). 
При решении надо учесть, что индекс элемента на 1 меньше порядко-
вого номера, поэтому вначале надо записать в массив b все элементы мас-
сива a с нечетными индексами, а затем — с четными: 
Task('Array57'); // Вариант 1 
var a := ReadArrInteger; 
var b := a[1::2] + a[0::2]; 
b.Print; 
Мы могли бы не связывать полученный массив с переменной b, а сра-
зу вывести его: 
Task('Array57'); // Вариант 1a 
var a := ReadArrInteger; 
(a[1::2] + a[0::2]).Print; 
Это не нарушает условия задачи, так как в данном случае мы также 
сформировали новый массив (просто при этом мы не связали созданный 
массив с каким-либо именем). 
Для сравнения приведем решение, использующее цикл: 
Task('Array57'); // Вариант 2 
var a := ReadArrInteger; 
var b := new integer[a.Length]; 
for var i := 0 to a.Length div 2 - 1 do 
b[i] := a[2 * i + 1]; 
for var i := 0 to (a.Length + 1) div 2 - 1 do 
b[a.Length div 2 + i] := a[2 * i]; 
b.Print; 
Разумеется, по части наглядности и простоты реализации этот вариант 
не выдерживает сравнения с предыдущим. Правда, он более эффективно 
использует память: кроме исходного массива a память выделяется только 
для результирующего массива b. В первом варианте память выделялась для 
массива a, для каждого из двух срезов, а также для суммы этих срезов 
(ссылка на которую записывалась в b). Если считать, что массив a содер-
жит N элементов, то во втором варианте программы выделялась память для 
хранения 2N элементов (массивы a и b), а в первом — для хранения 3N 
элементов (массив a, два среза и их сумма). Однако в большинстве ситуа-
ций подобный «перерасход» памяти (и связанное с ним небольшое замед-
ление алгоритма) можно не принимать во внимание.

Download 1.62 Mb.

Do'stlaringiz bilan baham:
1   ...   55   56   57   58   59   60   61   62   ...   71




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling