русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Массивы массивов


Дата добавления: 2013-12-23; просмотров: 824; Нарушение авторских прав


Еще одним видом массивов C# являются массивы массивов, называемые также изрезанными массивами (jagged arrays). Такой массив массивов можно рассматривать как одномерный массив, его элементы являются массивами, элементы которых, в свою очередь снова могут быть массивами, и так может продолжаться до некоторого уровня вложенности.

В каких ситуациях может возникать необходимость в таких структурах данных? Эти массивы могут применяться для представления деревьев, у которых узлы могут иметь произвольное число потомков. Таковым может быть, например, генеалогическое дерево. Вершины первого уровня - Fathers, представляющие отцов, могут задаваться одномерным массивом, так что Fathers[i] - это i-й отец. Вершины второго уровня представляются массивом массивов - Children, так что Children[i] - это массив детей i-го отца, а Children[i][j] - это j-й ребенок i-го отца. Для представления внуков понадобится третий уровень, так что GrandChildren [i][j][k] будет представлять к-го внука j-го ребенка i-го отца.

Есть некоторые особенности в объявлении и инициализации таких массивов. Если при объявлении типа многомерных массивов для указания размерности использовались запятые, то для изрезанных массивов применяется более ясная символика - совокупности пар квадратных скобок; например, int[][] задает массив, элементы которого - одномерные массивы элементов типа int.

Сложнее с созданием самих массивов и их инициализацией. Здесь нельзя вызвать конструктор new int[3][5], поскольку он не задает изрезанный массив. Фактически нужно вызывать конструктор для каждого массива на самом нижнем уровне. В этом и состоит сложность объявления таких массивов. Начну с формального примера:

//массив массивов - формальный пример //объявление и инициализация int[][] jagger = new int[3][] { new int[] {5,7,9,11}, new int[] {2,8}, new int[] {6,12,4} };

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



int[][] jagger1 = new int[3][] { new int[4], new int[2], new int[3] };

В этом случае элементы массива получат при инициализации нулевые значения. Реальную инициализацию нужно будет выполнять программным путем. Стоит заметить, что в конструкторе верхнего уровня константу 3 можно опустить и писать просто new int[][]. Самое забавное, что вызов этого конструктора можно вообще опустить, он будет подразумеваться:

int[][] jagger2 = { new int[4], new int[2], new int[3] };

Но вот конструкторы нижнего уровня необходимы. Еще одно важное замечание - динамические массивы возможны и здесь. В общем случае, границы на любом уровне могут быть выражениями, зависящими от переменных. Более того, допустимо, чтобы массивы на нижнем уровне были многомерными. Но это уже "от лукавого", вряд ли стоит пользоваться такими сложными структурами данных, ведь с ними предстоит еще и работать.

Приведу теперь чуть более реальный пример, описывающий простое генеалогическое дерево, которое условно назову "отцы и дети":

/// <summary>/// массив массивов -"Отцы и дети"/// </summary>public void GenTree() { int Fcount = 3; string[] Fathers = new string[Fcount]; Fathers[0] = "Николай"; Fathers[1] = "Сергей"; Fathers[2] = "Петр"; string[][] Children = new string[Fcount][]; Children[0] = new string[] {"Ольга", "Федор"}; Children[1] = new string[] {"Сергей", "Валентина", "Ира", "Дмитрий"}; Children[2] = new string[] {"Мария", "Ирина", "Надежда"}; Arrs.PrintAr3(Fathers, Children); }

Здесь отцов описывает обычный динамический одномерный массив Fathers. Для описания детей этих отцов необходим уже массив массивов, который также является динамическим на верхнем уровне, поскольку число его элементов совпадает с числом элементов массива Fathers. Здесь показан еще один способ создания таких массивов. Вначале конструируется массив верхнего уровня, содержащий ссылки со значением void. А затем на нижнем уровне конструктор создает настоящие массивы в динамической памяти, с которыми и связываются ссылки.

Я не буду демонстрировать работу с генеалогическим деревом, ограничусь лишь печатью этого массива. Здесь есть несколько поучительных моментов. В классе Arrs для печати массива создан специальный метод PrintAr3, которому в качестве аргументов передаются массивы Fathers и Children. Вот текст данной процедуры:

/// <summary> /// Печать дерева "Отцы и дети", /// заданного массивами Fathers и Children /// </summary> /// <param name="Fathers">массив отцов</param> /// <param name="Children"> массив массивов детей</param> public static void PrintAr3(string[] Fathers, string[][] Children) { for (int i = 0; i < Fathers.Length; i++) { Console.WriteLine("Отец : {0}; Его дети:", Fathers[i]); for (int j = 0; j < Children[i].Length; j++) Console.Write(Children[i][j] + " "); Console.WriteLine(); } }//PrintAr3

Приведу некоторые комментарии к этой процедуре.

  • Внешний цикл по i организован по числу элементов массива Fathers. Заметьте, здесь используется свойство Length, в отличие от ранее применяемого метода GetLength.
  • В этом цикле с тем же успехом можно было бы использовать и имя массива Children. Свойство Length для него возвращает число элементов верхнего уровня, совпадающее, как уже говорилось, с числом элементов массива Fathers.
  • Во внутреннем цикле свойство Length вызывается для каждого элемента Children[i], который является массивом.
  • Остальные детали, надеюсь, понятны.

Приведу вывод, полученный в результате работы процедуры PrintAr3.


Рис. 6.3. Дерево "Отцы и дети"



<== предыдущая лекция | следующая лекция ==>
Многомерные массивы | Алгоритмы и задачи


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


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

Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.002 сек.