Файл: 1_C#_Введение_в_программирование_Уч_пособ_(Марченко-2005).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2025
Просмотров: 1343
Скачиваний: 3
набором методов для создания, управления, поиска, и сортировки, элементов массива. К числу таких методов и свойств, в частности, относятся свойства:
public int Length {get;}
Возвращает целое число представляющее общее количество элементов во всех измерениях массива.
public int Rank {get;}
Возвращает целое число представляющее количество измерений массива.
И методы:
public static Array CreateInstance(Type, int, int);
Статический метод (один из вариантов), создаёт массив элементов заданного типа и определённой размерности.
public void SetValue(object, int, int);
Присваивает элементу массива значение, представленное первым параметром (один из вариантов).
public object GetValue(int, int);
Извлекает значение из двумерного массива по индексам (один из вариантов).
using System;
public class DemoArray
{
public static void Main()
{
//Создали и проинициализировали двумерный массив строк. Array myArray=Array.CreateInstance( typeof(String), 2, 4 ); myArray.SetValue( "The quarter moon ", 0, 0 ); myArray.SetValue( "comes out, ", 0, 1 );
myArray.SetValue( "leaves", 0, 2 ); myArray.SetValue( "a fog,", 0, 3 ); myArray.SetValue( "takes out", 1, 0 ); myArray.SetValue( "a knife", 1, 1 ); myArray.SetValue( "from", 1, 2 ); myArray.SetValue( "a pocket.", 1, 3 );
//Показали содержимое массива.
Console.WriteLine( "The Array contains the following values:" );
for ( int i = myArray.GetLowerBound(0); i <= myArray.GetUpperBound(0); i++ )
for ( int j = myArray.GetLowerBound(1); j <= myArray.GetUpperBound(1); j++ ) Console.WriteLine( "\t[{0},{1}]:\t{2}", i, j, myArray.GetValue( i, j ) );
}
}
Реализация сортировки в массиве стандартными методами
Массив элементов – это всегда особый класс, независимо от типа образующих его элементов, производный от базового класса Array.
Класс Array является основой для любого массива и предоставляет методы для создания, манипулирования (преобразования), поиска и сортировки на множестве элементов массива.
В частности, варианты метода Sort() обеспечивают реализацию механизмов сортировки элементов ОДНОМЕРНОГО массива объектов (в смысле представителей класса Object).
Сортировка элементов предполагает:
ПЕРЕБОР всего множества (или его части) элементов массива, СРАВНЕНИЕ (значений) элементов массива в соответствии с определённым
критерием сравнения. Критерии и алгоритмы сравнения могут задаваться либо с помощью массивов ключей, либо реализацией интерфейса IComparable.
Следующий вариант метода Sort сортирует полное множество элементов одноразмерного массива с использованием стандартного интерфейса сравнения.
public static void Sort(Array);
Стандартный интерфейс сравнения способен распознавать значения элементов массива и сравнивать эти элементы между собой.
Таким образом, никаких проблем не существует, если надо сравнить и переупорядочить массивы элементов базовых типов. Относительно …, System.Int16,
41
System.Int32, System.Int64, …,System.Double,… всегда можно сказать, какой из сравниваемых элементов больше, а какой меньше.
Сортировка элементов массива (массива целевых элементов) также может быть произведена с помощью вспомогательного массива ключей. Суть подобной сортировки заключается в том, что между элементами массива ключей и элементами сортируемого массива устанавливается соответствие. В частном случае, если количество элементов массива ключей оказывается равным количеству элементов сортируемого массива, это соответствие оказывается взаимнооднозначным. При этом сортируются элементы массива ключей. Предполагается, что используемый при этом интерфейс сравнения способен обеспечить необходимые алгоритмы.
При сортировке элементов массива ключей каждая из возможных перестановок элементов массива сопровождается перестановкой соответствующих item’ов массива. Таким образом, упорядочение массива целевых элементов осуществляется вне зависимости от реальных значений этих элементов данного массива. Читаются и сравниваются значения массива ключей, сами же элементы целевого массива перемещаются в соответствии с перемещениями элементов массива.
public static void Sort(Array, Array);
using System; namespace SortArrays
{
class Class1
{
static void Main(string[] args)
{
int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив. int[] keys = {10,1,2,3,4,5,6,7,8,9}; // Массив ключей.
for (i = 0; i < 10; i++) Console.WriteLine(“{0}: {1}”, i, iArr[i]); // Сортировка массива с использованием ключей. System.Array.Sort(keys,iArr);
Console.WriteLine(“=================================================”); for (i = 0; i < 10; i++) Console.WriteLine(“{0}: {1}”, i, iArr[i]);
}
}
}
В процессе сортировки массива ключей элемент со значением ключа 10 перемещается в конец массива. При этом нулевой элемент целевого массива со значением 0 перемещается на последнюю позицию.
Целевой массив и массив ключей вида при сортировке
int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив. int[] keys = {9,8,7,6,5,4,3,2,1,0}; // Массив ключей.
обеспечивают размещение элементов целевого массива в обратном порядке. Следующее сочетание значений целевого массива и массива ключей обеспечивает
изменение расположения первых четырёх элементов целевого массива:
int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив. int[] keys = {3,2,1,0}; // Массив ключей.
А такие наборы значений целевого и ключевого элементов массива при сортировке с использованием массива ключей обеспечивают изменение порядка целевых элементов массива с индексами 4, 5, 6, 7.
int[] iArr = {0,1,2,3,4,5,6,7,8,9}; int[] keys = {0,1,2,9,8,7,6,10,11,12};
Но самое главное и самое интересное в методе сортировки с использованием ключевого массива – это то, что в этом никаким образом не участвуют значения элементов целевого массива.
Надо отсортировать (изменить порядок расположения) составляющих массив массивов компонентов – надо всего лишь установить соответствие между элементами целевого массива и элементами массива ключей – и вызвать
42
соответствующий вариант метода сортировки. Составляющие массива массивов будут восприняты как объекты-представители класса object и, не вдаваясь в подробности (а по какому принципу упорядочивать массивы?) будут переупорядочены в соответствии с новым порядком расположения элементов ключевого массива.
int[][] iArr = new int[3][]{ new int[]{0},
new int[]{0,1},
new int[]{0,1,2,3,4,5,6,7,8,9} };
int[] keys = {3,2,1};
Вариант метода, позволяющего организовать сортировку подмножества элементов целевого массива, начиная с элемента, заданного вторым параметром метода и включающим количество элементов, заданным вторым параметром.
public static void Sort(Array,int,int);
Вариант метода сортировки основанный на сортировке элементов ключевого массива. Обеспечивает сортировку подмножества массива. Принципы выделения подмножества аналогичны рассмотренному выше варианту метода сортировки. public static void Sort(Array,Array,int,int);
Сортировка на основе сравнения пар объектов-членов одномерного массива с использованием стандартного интерфейса сравнения
public static void Sort(Array,IComparer);
//Сортировка элементов с использованием стандартного Компарера.
//iArr – одномерный массив целочисленных значений.
//System.Collections.Comparer.DefaultInvariant стандартный Компарер.
try
{
System.Array.Sort(iArr,System.Collections.Comparer.DefaultInvariant);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
System.Collections.Comparer.DefaultInvariant - интерфейс определяет обобщённый метод сравнения значений (класса или типа), переопределение которого позволяет задать собственный специфический для данного класса метод сравнения элементов массива (interface implemented by each element of the Array).
using System;
using System.Collections;
namespace SortArrays
{
///<summary>
///Данные для массива элементов.
///Подлежат сортировке в составе массива методом Sort.
///Главная проблема заключается в том, что никто из тех, кто обеспечивает
///встроенную сортировку, ни в классе Array, ни в классе Items не знает,
///как воспринимать и каким образом сравнивать между собой
///объекты-представители класса Items. Объекты itObj0 b itObj1
///со значениями полей (7,5) и (5,7) - кто из них «больше»?
///</summary>
class Items
{
///<summary>
///Конечно, можно об определении аксиом для установления отношения
///порядка между элементами множества объектов-представителей класса
///Items и о реализации соответствующих методов сравнения
///можно было позаботиться при объявлении класса и просто не допускать
///к стандартной сортировке объекты классов, в которых не определено
43
///отношение порядка, однако в .NET используется другой подход.
///<summary>
public int val1; public int val2;
public Items (int key1, int key2)
{
val1 = key1; val2 = key2;
}
}
///<summary>
///Предполагается, что отношение порядка над элементами
///множества объектов-представителей соответствующего
///класса может быть введено в любой момент. Для этого
///достаточно иметь доступ к значениям соответствующих
///полей объектов.
///Для этого достаточно воспользоваться стандартными
///библиотечными средствами .NET и реализовать (доопределить)
///соответствующие интерфейсы (заготовки методов) сравнения.
///Ниже объявляются два варианта процедур сравнения,
///использование которых позволяет реализовать стандартные
///алгоритмы сортировки, применяемые в классе Array.
///...КОМПАРАТОРЫ...
///</summary>
class myComparer0: IComparer
{
int IComparer.Compare(object obj1, object obj2)
{
if (((Items)obj1).val1 == ((Items)obj2).val1) return 0; if (((Items)obj1).val1 > ((Items)obj2).val1) return 1; if (((Items)obj1).val1 < ((Items)obj2).val1) return -1; else return 0;
}
}
class myComparer1: IComparer
{
int IComparer.Compare(object obj1, object obj2)
{
if (((Items)obj1).val2 == ((Items)obj2).val1) return 0; if (((Items)obj1).val2 > ((Items)obj2).val2) return 1; if (((Items)obj1).val2 < ((Items)obj2).val2) return -1; else return 0;
}
}
///<summary>
///После реализации соответствующего интерфейса объекты-компараторы,
///«профессиональные сравниватели», обеспечивают реализацию
///стандартных алгоритмов сортировки.
///</summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//Объект-генератор «случайных» чисел.
//Стартует c использованием a time-dependent default seed value. Random rnd = new Random();
int i;
//Массив Items.
Items[] itArr = new Items[10];
// Создали две версии Компареров, способных сравнивать пары
44
// объектов-представителей класса Items. myComparer0 c0 = new myComparer0(); myComparer1 c1 = new myComparer1();
Console.WriteLine(“=================================================”); // Проинициализировали массив объектов-представителей класса Items. for (i = 0; i < 10; i++)
{
itArr[i] = new Items(rnd.Next(0,10),rnd.Next(0,10));
}
for (i = 0; i < 10; i++)
{
Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);
}
//Сортируются элементы массива типа Items.
//Условием успешной сортировки элементов массива является реализация
//интерфейса IComparer. Если Компарер не сумеет справиться с
//поставленной задачей - будет возбуждено исключение.
try
{
System.Array.Sort(itArr,c0);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine(“=================================================”); for (i = 0; i < 10; i++)
{
Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);
}
Console.WriteLine(“=================================================”);
//Сортируются элементы массива типа Items.
//Условием успешной сортировки элементов массива является реализация
//интерфейса IComparer.
try
{
System.Array.Sort(itArr,c1);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
for (i = 0; i < 10; i++)
{
Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);
}
}
}
}
Подробнее о массивах массивов (jagged array)
A jagged array также называют “массивом массивов”.
Прежде всего, элементы зубчатого массива на одном и том же уровне (элементы одной размерности) могут иметь разные размеры. На этих массивах функция GetLength() и свойство Rank показывают результаты, аналогичные простым одномерным массивам.
Рассмотрим примеры объявления, инициализации и доступа к элементам jagged arrays.
Вот объявление a single-dimensional (ОДНОМЕРНОГО!) массива, состоящего из трёх элементов, каждый из которых является одномерным массивом целых:
45
int[][] myJaggedArray = new int[3][];
Дальнейшее использование этого массива требует инициализации его элементов. Например, так:
myJaggedArray[0] = new int[5]; myJaggedArray[1] = new int[4]; myJaggedArray[2] = new int[2];
Каждый из элементов является single-dimensional массивом целых. Количество элементов каждого массива очевидно из соответствующих операторов определения.
Ниже показан пример использования заполняющей инициализации, при которой одновременно с определением (созданием) массивов производится присвоение элементам новорожденных массивов конкретных значений:
myJaggedArray[0] = new int[] {1,3,5,7,9}; myJaggedArray[1] = new int[] {0,2,4,6}; myJaggedArray[2] = new int[] {11,22};
Вышеупомянутый массив может быть объявлен и проинициализирован и таким образом:
int[][] myJaggedArray = new int [][]
{
new int[] {1,3,5,7,9}, new int[] {0,2,4,6}, new int[] {11,22}
};
И ещё один эквивалентный способ инициализации массива. В этом случае используется неявная инициализация на верхнем уровне, как при инициализации обычного одномерного массива. Важно (!) что при определении составляющих этого массива операция new опущена быть не может. Каждая компонента требует явного применения операции new или присвоения ссылки на ранее созданный одномерный массив:
int[][] myJaggedArray = { new int[] {1,3,5,7,9}, new int[] {0,2,4,6},
new int[] {11,22} };
Доступ к элементам ступенчатого массива обеспечивается посредством выражений индексации:
//Assign 33 to the second element of the first array: myJaggedArray[0][1] = 33;
//Assign 44 to the second element of the third array: myJaggedArray[2][1] = 44;
C# позволяет собирать разнообразные конструкции на основе jagged многомерных массивов. Ниже приводится пример объявления и инициализации одномерного jagged array, содержащего в качестве элементов двумерные массивы различных размеров:
int[][,] myJaggedArray = new int [3][,]
{
new int[,] { {1,3}, {5,7} },
new int[,] { {0,2}, {4,6}, {8,10} }, new int[,] { {11,22}, {99,88}, {0,9} }
};
Доступ к отдельным элементам jagged массива обеспечивается различными комбинациями выражений индексации. В приводимом ниже примере выводится значение элемента массива [1,0], расположенного по нулевому индексу myJaggedArray (это 5):
Console.Write(“{0}”, myJaggedArray[0][1,0]);
46