Многомерные зубчатые массивы

Если вы пришли из мира C/C++ или Java, то, скорее всего, уже знакомы с зубчатыми (Jagged) массивами, поскольку эти языки не поддерживают прямоугольных массивов, как это делает С#. Единственный способ реализации многомерных массивов в этих языках — создавать массивы массивов, а именно это и представляют собой зубчатые массивы.

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

Синтаксический шаблон объявления зубчатого массива в С# подобен тому, который принят в С++ и Java. В следующем примере показано, как развернуть и использовать зубчатый массив:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Text;
public class EntryPoint {
static void Main()   {
int[] [] jagged = new int[3] [];
jagged[0] = new int[]  { 1, 2};
jagged[l] = new int[]  {1, 2, 3, 4, 5};
jagged[2] = new int[]  {6, 5, 4};
foreach ( int[] ar in jagged )  {
StringBuilder sb = new StringBuilder();
foreach ( int n in ar )  {
sb.AppendFormat ( "{0} ", n ) ;
}
Console.WriteLine ( sb.ToString () );
}
Console.WriteLine();
for ( int i = 0;
i < jagged.Length; ++i )  {
StringBuilder sb = new StringBuilder();
for( int j = 0; j < jagged[i].Length; ++j )  {
sb.AppendFormat( "{0} ", jagged[i][j] );
}
Console.WriteLine ( sb.ToString () );
}

Как видите, распределение и создание зубчатого массива несколько сложнее, чем массива прямоугольного, поскольку нужно обрабатывать распределения всех подмас-сивов индивидуально, в то время как прямоугольный массив распределяется за один прием.

Обратите внимание на “зубчатый” вывод, который объясняется разными размерами каждого подмассива:


1 2 3 4 5 6

В данном примере демонстрируются два способа выполнения итерации по массиву — просто чтобы показать синтаксис доступа к индивидуальным элементам внутри зубчатого массива и его отличие от обращения к элементам прямоугольного массива. Синтаксис подобен принятому в языках С++ и Java.

Метод foreach для итерации по массиву более элегантен, и как будет показано далее, его применение позволяет использовать тот же код для итерации по коллекциям, которые могут и не быть массивами.

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

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

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

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

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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100