Programming Taskbook 0
Download 1.62 Mb. Pdf ko'rish
|
Abramyan-Pascal2016-1
- Bu sahifa navigatsiya:
- Array57 ); // Вариант 1
- Array57 ); // Вариант 1a
- Array57 ); // Вариант 2
Глава 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: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling