Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 8:

Интерфейсы

< Лекция 7 || Лекция 8: 123 || Лекция 9 >

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

При сортировке элементов массива ключей каждая из возможных перестановок элементов массива сопровождается перестановкой соответствующих item'ов массива. Таким образом, упорядочение массива целевых элементов осуществляется вне зависимости от реальных значений этих элементов данного массива. Читаются и сравниваются значения массива ключей, сами же элементы целевого массива перемещаются в соответствии с перемещениями элементов массива.

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 (int 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};

Но самое главное и самое интересное в методе сортировки с использованием ключевого массива – это то, что в этом никаким образом не участвуют значения элементов целевого массива.

Для сортировки (изменения порядка расположения) составляющих массив массивов компонентов надо всего лишь установить соответствие между элементами целевого массива и элементами массива ключей – и вызвать соответствующий вариант метода сортировки. Составляющие массива массивов будут восприняты как объекты — представители класса 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 – свойство, которое обеспечивает доступ к объекту, реализующему обобщенный метод сравнения.

Для любого класса на основе интерфейса IComparer можно создать собственный класс-КОМПАРЕР, в котором можно будет реализовать специфический для данного класса сортируемых элементов метод сравнения (interface implemented by each element of the Array).

using System;
using System.Collections;

namespace SortArrays
{
// Данные для массива элементов.
// Подлежат сортировке в составе массива методом Sort.
// Главная проблема заключается в том, что никто из тех, кто обеспечивает
// встроенную сортировку, ни в классе Array, ни в классе Points не знает,
// как воспринимать и каким образом сравнивать между собой
// объекты-представители класса Points. Объекты p0 и p1
// со значениями координат (7,5) и (5,7) – кто из них "больше"?
class Points
{
// Конечно, можно говорить о введении аксиом для установления отношения
// порядка между элементами множества объектов – представителей класса
// Points и о реализации соответствующих методов сравнения;
// также можно было бы позаботиться при объявлении класса о том,
// чтобы просто не допускать к стандартной сортировке
// объекты классов, в которых не определено
// отношение порядка. Однако в .NET используется другой подход.
public int x;
public int y;
public Points (int key1, int key2)
{
 x = key1;
 y = key2;
}
// Вычисляется расстояние от начала координат.
public int R
{
get
{
 return (int)(Math.Sqrt(x*x+y*y));
}     
}   
}
    
// Предполагается, что отношение порядка над элементами
// множества объектов – представителей соответствующего
// класса может быть введено в любой момент. Для этого
// достаточно иметь четкое представление о критериях
// установления порядка на множестве объектов – представителей
// данного класса и иметь доступ к значениям соответствующих
// полей объектов.
// Стандартные библиотечные средства .NET позволяют
// реализовать (доопределить) соответствующие интерфейсы
// (заготовки) для реализации методов сравнения.
// Ниже объявляется вариант процедуры сравнения,
// использование которого позволяет реализовать стандартные
// алгоритмы сортировки, применяемые в классе Array.
// ...КОМПАРЕР...   

class myComparer: IComparer
{
// Предлагаемый метод сравнения возвращает разность расстояний
// двух точек (вычисляется по теореме Пифагора) от начала координат
// – точки с координатами (0,0). Чем ближе точки к началу координат
// – тем они меньше. 
	
int IComparer.Compare(object obj1, object obj2)
{
    return ((Points)obj1).R - ((Points)obj2).R; 
}
}

// После реализации соответствующего интерфейса объект-КОМПАРЕР
// обеспечивает реализацию стандартного алгоритма сортировки.
class Class1
{

static void Main(string[] args)
{
    // Объект-генератор "случайных" чисел. 
	Random rnd = new Random();

	int i;
    // Массив Points.
    Points[] itArr = new Points[10];
	
   // Создали Компарер, способный сравнивать пары
	// объектов-представителей класса Points.  
	myComparer c = new myComparer();
	
Console.WriteLine("============================================");

	// Проинициализировали массив объектов – представителей класса Points. 
	for (i = 0; i < 10; i++)
	{
		itArr[i] = new Points(rnd.Next(0,10),rnd.Next(0,10));
	}

	for (i = 0; i < 10; i++)
	{
		Console.WriteLine("{0}: {1},{2}", i, itArr[i].x, itArr[i].y);
	}

	// Сортируются элементы массива типа Points.
	// Условием успешной сортировки элементов массива является реализация
	// интерфейса IComparer. Если Компарер не сумеет справиться с
	// поставленной задачей – будет возбуждено исключение.
	try
	{
		System.Array.Sort(itArr,c);
	}
	catch (Exception ex)
	{
			Console.WriteLine(ex);			
	}

	Console.WriteLine("============================================");
	for (i = 0; i < 10; i++)
	{
		Console.WriteLine("{0}: {1},{2}", i, itArr[i].x, itArr[i].y);
	}

	Console.WriteLine("============================================");
}
}
}
Листинг 8.3.
< Лекция 7 || Лекция 8: 123 || Лекция 9 >
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2