Мы не будем в тексте лекции разбирать реализацию проекта "Соревнование по триатлону". В видео записи этой лекции разбор был проведен достаточно подробно, а сам проект при желании доступен для просмотра.
Остановимся на правилах, сформулированных в шуточной стихотворной форме, позволяющих лучше запомнить основные моменты в реализации алгоритмов вычисления суммы, произведения, минимального и максимального элементов множества. Правила сформулированы следующим образом:
Чтобы минимум найти,
Правил помнить нужно три:
Объявить,
Задать,
Сравнить, -
Ничего не позабыть!
Правило "Объявить" говорит, что прежде всего следует объявить переменную с содержательным именем, например, min, которая в конечном итоге будет содержать минимальный элемент рассматриваемого множества.
Правило "Задать" говорит, что в момент объявления этой переменной следует задать ей "правильное" значение. Например, при нахождении минимума переменной следует дать значение, заведомо превосходящее значения всех элементов массива.
Правило "Сравнить" говорит, что переменную min следует последовательно сравнивать с элементами множества. Если при сравнении окажется, что некоторый элемент меньше чем min, то переменная min получает новое значение. Это гарантирует, что min является минимальным элементом среди всех просмотренных элементов. Сравнив с этой переменной все элементы множества, мы гарантируем, что min является минимальным элементом всего множества.
Эти три правила действуют при вычислении максимального элемента, при нахождении суммы и произведения элементов множества. В каждом случае следует правильно задавать начальное значение переменной.
Эти правила действуют и тогда, когда рассматривается множество элементов сколь угодно большого размера. Данная лекция как раз посвящена рассмотрению больших множеств. До сих пор мы рассматривали простые данные – числа типа int и double, булевские переменные типа bool, строки текста типа string. Пришла пора познакомиться со сложными структурами данных, без которых невозможно решение практических задач, стоящих перед программистами. Известная книга одного из выдающихся программистов – Никласа Вирта – автора языка Pascal и других языков программирования называется "Программа = Алгоритм + Структура данных". Когда мы создаем программу, то мы должны спроектировать подходящие для решения задачи структуры данных и придумать алгоритм обработки этих данных, приводящий к решению поставленной задачи. Эти две стороны одной программы проектируются одновременно. Нельзя придумать алгоритм, не понимая, как устроены данные. В свою очередь структура данных во многом зависит от алгоритма, обрабатывающего эти данные.
Простейшей из сложных структур данных и, пожалуй, наиболее широко распространенной структурой данных является массив.
Определение
Массивом называется упорядоченная совокупность элементов одного типа.
В этом определении отмечаются две особенности массивов. Во-первых, все элементы массива имеют один и тот же тип. Это требование понятно. Менее понятно, как достигается упорядоченность элементов? Поговорим об этом подробнее. Простым способом упорядочения совокупности элементов является нумерация элементов. В математике широко используется понятие последовательности элементов: a1, a2, a3, … an. Каждый элемент последовательности имеет свой номер, который называют индексом элемента. Индекс однозначно определяет элемент последовательности. Элементы последовательности упорядочены. За элементом с индексом j следует элемент с индексом j+1, а предшествует элемент с индексом j-1. В математике последовательность может иметь бесконечно много элементов. В программировании бесконечности нет и массив всегда имеет конечное число элементов.
Число элементов массива называется его размером. Другая важнейшая характеристика массива его размерность. Размерность массива - это число индексов, используемых для упорядочения элементов массива. Если массив одномерный (размерность равна единице), то массив является аналогом последовательности с конечным числом элементов. Одномерный массив можно рассматривать как строку, содержащую n элементов, где n – размер массива. Двумерный массив можно рассматривать как таблицу, состоящую из m строк и n столбцов. Каждый элемент двумерного массива однозначно характеризуется двумя индексами – номером строки и номером столбца. Размер двумерного массива равен m * n. Увеличивая на единицу размерность массива, мы добавляем новое измерение. Приведу понятную аналогию. Пусть у нас есть тетрадь по арифметике в клеточку. Тогда одна строчка в этой тетради может рассматриваться как одномерный массив, который можно заполнять цифрами. Страничка в тетради представляет собой двумерный массив, а сама тетрадь с пронумерованными страницами является трехмерным массивом. Если в портфеле несколько таких тетрадей и они пронумерованы, то можно говорить о массиве размерности 4. Зная четыре индекса – номер тетради, номер страницы, номер строки и номер столбца, можно однозначно определить, о какой клеточке из всего множества клеточек идет речь и какая цифра записана в этой клеточке.
Общая схема объявления переменных такова. Объявление может быть сделано без инициализации и тогда оно имеет вид:
<тип переменной><имя переменной>;
При объявлении с инициализацией добавляется значение:
<тип переменной><имя переменной> = <значение переменной>;
Эта схема сохраняется и при объявлении массива. Как указать, что переменная является массивом? В разных языках синтаксис может быть немного различным. В языке C# (C++, Java) это делается так – вначале указывается тип элементов массива, затем в квадратных скобках ставятся запятые в зависимости от размерности массива. Размерность массива равна числу запятых плюс единица. При задании одномерного массива запятые не ставятся.
Пример объявления массивов без инициализации:
int[] ar1, ar2; string[,] sar1;
Здесь ar1 и ar2 – одномерные массивы с элементами типа int. Массив sar1 – это двумерный массив, элементы которого имеют тип string. Заметьте, размер массива не входит в понятие типа массива. Массивы одной размерности и с одним и тем же типом элементов имеют один и тот же тип независимо от размера массива.
При объявлении с инициализацией массивы получают значение. есть две возможности выполнить инициализацию. Первая – задать значение в виде константного массива. Вот пример:
int[] mas = {5, 12, 20, 32};
В этом случае элементы массива задаются списком, заключенным в фигурные скобки. В данном примере массив mas – это одномерный массив размера 4, где первый элемент имеет значение 5, а последний – 32. Сложнее, но возможно задать константный массив размерности больше единицы.
Другая возможность инициализации массива в момент объявления – это создать массив, используя вызов конструктора массива. Вот как это делается:
int[] massiv = new int[10]; double[,] dar = new double[n, m];
В результате этих объявлений создан одномерный целочисленный массив с именем massiv размера 10 и двумерный массив dar с элементами типа double, у которого n строк и m столбцов. Переменные n и m должны быть целочисленного типа и иметь значения в момент объявления массива dar. Ключевое слово new в этих объявлениях задает вызов конструктора, создающего массив. Остается выяснить, какие же значения имеют элементы массива, созданного конструктором? Ведь в отличие от задания константного массива, никакие значения конструктору массива не передаются. Ответ прост. Все элементы массива получают одно и тоже значение, определяемое значением по умолчанию, принятого для элементов заданного типа. Для арифметических типов int и double значением по умолчанию является число ноль, для типа string – пустая строка.
По каждому измерению элементы нумеруются последовательно: i, i+1, i+2 и так далее. Но каково начальное значение индекса? В языке C# принято, что нумерация начинается с нуля. Так что в одномерном массиве размера n индексы изменяются в пределах от нуля (для первого элемента) до n-1 (индекс последнего элемента). В двумерном массиве элемент с индексами 3 и 5, что на языке C# пишется как mas[3, 5], обозначает элемент четвертой строки шестого столбца массива mas.
Покажем, как работать с массивами на примере классических задач вычисления суммы элементов массива и других его характеристик. В лекции, представленной на видео, построен простой проект, демонстрирующий возможное решение этих задач на примере конкретного массива. Проект доступен в этом уроке. Приведу интерфейс проекта:
(рис 2.1) Интерфейс проекта: Вычисление характеристик массива
Интерфейс предельно прост. Четыре кнопки для подсчета характеристик массива, Четыре окошка, где эти характеристики будут показаны. Вот как выглядит в этом проекте обработчик события Click для кнопки "Сумма":
private void buttonSum_Click(object sender, EventArgs e)
{
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
richTextBoxSum.Text = sum.ToString();
}
Массив arr доступен обработчику события. Он определен следующим образом:
int[] arr = { 1, 2, 3, 4 };
Не буду приводить обработчики событий для других кнопок. Вместо этого приведу тексты функций, вычисляющих характеристики массива. Вот код функции Sum, вычисляющей сумму элементов массива:
/// <summary>
/// Сумма элементов массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>сумма его элементов</returns>
int Sum(int[] arr)
{
int n = arr.Length;
int sum = 0;
for (int i = 0; i < n; i++)
sum += arr[i];
return sum;
}
Наша функция имеет один параметр – сам массив. В теле функции можно выяснить, каков размер массива, используя свойство Length, которым обладают объекты типа массив. Далее вычисление суммы следует правилам "Объявить, задать, сложить".
Давайте сравним код этой функции с кодом ранее написанной функции, вычисляющей сумму трех элементов:
/// <summary>
/// Сумма трех аргументов
/// </summary>
/// <param name="x1">аргумент1</param>
/// <param name="x2">аргумент2</param>
/// <param name="x3">аргумент3</param>
/// <returns>сумма x1 + x2 + x3</returns>
int Sum(int x1, int x2, int x3)
{
// return x1 + x2 + x3;
int sum = 0;//вводим переменную для суммы с начальным значением 0
sum = sum + x1; //прибавляем первое слагаемое
sum = sum + x2; //прибавляем второе слагаемое
sum = sum + x3; //прибавляем третье слагаемое
return sum; //возвращаем результат
}
Посмотрите, насколько общее решение, позволяющее вычислить сумму элементов массива независимо от того, сколько в нем элементов элегантнее частного решения вычисления суммы трех элементов. Эта элегантность и красота решения достигается за счет использования такой структуры данных как массив.
А можно ли столь же просто вычислить сумму массива большей размерности? Оказывается, да. Вот соответствующий код для двумерного массива:
/// Сумма элементов двумерного массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>сумма его элементов</returns>
int Sum_Best(int[,] arr)
{
int n = arr.Length;
int sum = 0;
foreach (int item in arr)
sum += item;
return sum;
}
Здесь использован ранее не встречающийся оператор цикла foreach, который удобно применять при работе с массивами, поскольку он позволяет последовательно читать все элементы массива вне зависимости от размерности массива.
Следует заметить, что в отличие от цикла for в цикле foreach элементы массива можно только читать, но их нельзя изменять.
Приведу уже без дополнительных комментариев функции, вычисляющие произведение, максимальный и минимальный элементы массивов:
/// <summary>
/// Произведение элементов массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>произведение его элементов</returns>
int Product(int[] arr)
{
int n = arr.Length;
int prod = 1;
for (int i = 0; i < n; i++)
prod *= arr[i];
return prod;
}
/// <summary>
/// Минимальный элемент массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns> его минимальный элемент</returns>
int Min(int[] arr)
{
int n = arr.Length;
int min = int.MaxValue;
for (int i = 0; i < n; i++)
if( arr[i] < min) min = arr[i];
return min;
}
/// <summary>
/// Максимальный элемент массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns> его максимальный элемент</returns>
int Max(int[] arr)
{
int n = arr.Length;
int max = int.MinValue;
for (int i = 0; i < n; i++)
if (arr[i] > max) max = arr[i];
return max;
}
В проекте, сопровождающем лекцию, можно увидеть пример работы с двумерным массивом.
Переменные sum, prod, min, max, которые используются при вычислении соответствующих характеристик массива следует правильно инициализировать. В наших примерах кода используется рекомендованный способ инициализации, - сумму следует инициализировать нулем, произведение – единицей, минимум и максимум максимально возможным и минимально возможным значениями соответственно. Рекомендуемый способ не является единственно возможным.
Иногда для инициализации используется первый элемент массива. Это возможный прием, - во многих случаях такая инициализация корректно работает. Однако в ряде ситуаций она приводит к ошибкам, например, если исходный массив пуст или ищется максимальный элемент, удовлетворяющий некоторым дополнительным условиям.
При нахождении максимального элемента часто переменную max инициализируют отрицательным значением. Это корректно работает, если все элементы массива положительны, но в случаях, когда это предположение ошибочно, результат может быть не верным. Рекомендуемая нами схема инициализации корректно работает во всех ситуациях.
Мы не будем в тексте лекции разбирать реализацию проекта "Соревнование по триатлону". В видео записи этой лекции разбор был проведен достаточно подробно, а сам проект при желании доступен для просмотра.
Остановимся на правилах, сформулированных в шуточной стихотворной форме, позволяющих лучше запомнить основные моменты в реализации алгоритмов вычисления суммы, произведения, минимального и максимального элементов множества. Правила сформулированы следующим образом:
Чтобы минимум найти,
Правил помнить нужно три:
Объявить,
Задать,
Сравнить, -
Ничего не позабыть!
Правило "Объявить" говорит, что прежде всего следует объявить переменную с содержательным именем, например, min, которая в конечном итоге будет содержать минимальный элемент рассматриваемого множества.
Правило "Задать" говорит, что в момент объявления этой переменной следует задать ей "правильное" значение. Например, при нахождении минимума переменной следует дать значение, заведомо превосходящее значения всех элементов массива.
Правило "Сравнить" говорит, что переменную min следует последовательно сравнивать с элементами множества. Если при сравнении окажется, что некоторый элемент меньше чем min, то переменная min получает новое значение. Это гарантирует, что min является минимальным элементом среди всех просмотренных элементов. Сравнив с этой переменной все элементы множества, мы гарантируем, что min является минимальным элементом всего множества.
Эти три правила действуют при вычислении максимального элемента, при нахождении суммы и произведения элементов множества. В каждом случае следует правильно задавать начальное значение переменной.
Эти правила действуют и тогда, когда рассматривается множество элементов сколь угодно большого размера. Данная лекция как раз посвящена рассмотрению больших множеств. До сих пор мы рассматривали простые данные – числа типа int и double, булевские переменные типа bool, строки текста типа string. Пришла пора познакомиться со сложными структурами данных, без которых невозможно решение практических задач, стоящих перед программистами. Известная книга одного из выдающихся программистов – Никласа Вирта – автора языка Pascal и других языков программирования называется "Программа = Алгоритм + Структура данных". Когда мы создаем программу, то мы должны спроектировать подходящие для решения задачи структуры данных и придумать алгоритм обработки этих данных, приводящий к решению поставленной задачи. Эти две стороны одной программы проектируются одновременно. Нельзя придумать алгоритм, не понимая, как устроены данные. В свою очередь структура данных во многом зависит от алгоритма, обрабатывающего эти данные.
Простейшей из сложных структур данных и, пожалуй, наиболее широко распространенной структурой данных является массив.
Определение
Массивом называется упорядоченная совокупность элементов одного типа.
В этом определении отмечаются две особенности массивов. Во-первых, все элементы массива имеют один и тот же тип. Это требование понятно. Менее понятно, как достигается упорядоченность элементов? Поговорим об этом подробнее. Простым способом упорядочения совокупности элементов является нумерация элементов. В математике широко используется понятие последовательности элементов: a1, a2, a3, … an. Каждый элемент последовательности имеет свой номер, который называют индексом элемента. Индекс однозначно определяет элемент последовательности. Элементы последовательности упорядочены. За элементом с индексом j следует элемент с индексом j+1, а предшествует элемент с индексом j-1. В математике последовательность может иметь бесконечно много элементов. В программировании бесконечности нет и массив всегда имеет конечное число элементов.
Число элементов массива называется его размером. Другая важнейшая характеристика массива его размерность. Размерность массива - это число индексов, используемых для упорядочения элементов массива. Если массив одномерный (размерность равна единице), то массив является аналогом последовательности с конечным числом элементов. Одномерный массив можно рассматривать как строку, содержащую n элементов, где n – размер массива. Двумерный массив можно рассматривать как таблицу, состоящую из m строк и n столбцов. Каждый элемент двумерного массива однозначно характеризуется двумя индексами – номером строки и номером столбца. Размер двумерного массива равен m * n. Увеличивая на единицу размерность массива, мы добавляем новое измерение. Приведу понятную аналогию. Пусть у нас есть тетрадь по арифметике в клеточку. Тогда одна строчка в этой тетради может рассматриваться как одномерный массив, который можно заполнять цифрами. Страничка в тетради представляет собой двумерный массив, а сама тетрадь с пронумерованными страницами является трехмерным массивом. Если в портфеле несколько таких тетрадей и они пронумерованы, то можно говорить о массиве размерности 4. Зная четыре индекса – номер тетради, номер страницы, номер строки и номер столбца, можно однозначно определить, о какой клеточке из всего множества клеточек идет речь и какая цифра записана в этой клеточке.
Общая схема объявления переменных такова. Объявление может быть сделано без инициализации и тогда оно имеет вид:
<тип переменной><имя переменной>;
При объявлении с инициализацией добавляется значение:
<тип переменной><имя переменной> = <значение переменной>;
Эта схема сохраняется и при объявлении массива. Как указать, что переменная является массивом? В разных языках синтаксис может быть немного различным. В языке C# (C++, Java) это делается так – вначале указывается тип элементов массива, затем в квадратных скобках ставятся запятые в зависимости от размерности массива. Размерность массива равна числу запятых плюс единица. При задании одномерного массива запятые не ставятся.
Пример объявления массивов без инициализации:
int[] ar1, ar2; string[,] sar1;
Здесь ar1 и ar2 – одномерные массивы с элементами типа int. Массив sar1 – это двумерный массив, элементы которого имеют тип string. Заметьте, размер массива не входит в понятие типа массива. Массивы одной размерности и с одним и тем же типом элементов имеют один и тот же тип независимо от размера массива.
При объявлении с инициализацией массивы получают значение. есть две возможности выполнить инициализацию. Первая – задать значение в виде константного массива. Вот пример:
int[] mas = {5, 12, 20, 32};
В этом случае элементы массива задаются списком, заключенным в фигурные скобки. В данном примере массив mas – это одномерный массив размера 4, где первый элемент имеет значение 5, а последний – 32. Сложнее, но возможно задать константный массив размерности больше единицы.
Другая возможность инициализации массива в момент объявления – это создать массив, используя вызов конструктора массива. Вот как это делается:
int[] massiv = new int[10]; double[,] dar = new double[n, m];
В результате этих объявлений создан одномерный целочисленный массив с именем massiv размера 10 и двумерный массив dar с элементами типа double, у которого n строк и m столбцов. Переменные n и m должны быть целочисленного типа и иметь значения в момент объявления массива dar. Ключевое слово new в этих объявлениях задает вызов конструктора, создающего массив. Остается выяснить, какие же значения имеют элементы массива, созданного конструктором? Ведь в отличие от задания константного массива, никакие значения конструктору массива не передаются. Ответ прост. Все элементы массива получают одно и тоже значение, определяемое значением по умолчанию, принятого для элементов заданного типа. Для арифметических типов int и double значением по умолчанию является число ноль, для типа string – пустая строка.
По каждому измерению элементы нумеруются последовательно: i, i+1, i+2 и так далее. Но каково начальное значение индекса? В языке C# принято, что нумерация начинается с нуля. Так что в одномерном массиве размера n индексы изменяются в пределах от нуля (для первого элемента) до n-1 (индекс последнего элемента). В двумерном массиве элемент с индексами 3 и 5, что на языке C# пишется как mas[3, 5], обозначает элемент четвертой строки шестого столбца массива mas.
Покажем, как работать с массивами на примере классических задач вычисления суммы элементов массива и других его характеристик. В лекции, представленной на видео, построен простой проект, демонстрирующий возможное решение этих задач на примере конкретного массива. Проект доступен в этом уроке. Приведу интерфейс проекта:
(рис 2.1) Интерфейс проекта: Вычисление характеристик массива
Интерфейс предельно прост. Четыре кнопки для подсчета характеристик массива, Четыре окошка, где эти характеристики будут показаны. Вот как выглядит в этом проекте обработчик события Click для кнопки "Сумма":
private void buttonSum_Click(object sender, EventArgs e)
{
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
richTextBoxSum.Text = sum.ToString();
}
Массив arr доступен обработчику события. Он определен следующим образом:
int[] arr = { 1, 2, 3, 4 };
Не буду приводить обработчики событий для других кнопок. Вместо этого приведу тексты функций, вычисляющих характеристики массива. Вот код функции Sum, вычисляющей сумму элементов массива:
/// <summary>
/// Сумма элементов массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>сумма его элементов</returns>
int Sum(int[] arr)
{
int n = arr.Length;
int sum = 0;
for (int i = 0; i < n; i++)
sum += arr[i];
return sum;
}
Наша функция имеет один параметр – сам массив. В теле функции можно выяснить, каков размер массива, используя свойство Length, которым обладают объекты типа массив. Далее вычисление суммы следует правилам "Объявить, задать, сложить".
Давайте сравним код этой функции с кодом ранее написанной функции, вычисляющей сумму трех элементов:
/// <summary>
/// Сумма трех аргументов
/// </summary>
/// <param name="x1">аргумент1</param>
/// <param name="x2">аргумент2</param>
/// <param name="x3">аргумент3</param>
/// <returns>сумма x1 + x2 + x3</returns>
int Sum(int x1, int x2, int x3)
{
// return x1 + x2 + x3;
int sum = 0;//вводим переменную для суммы с начальным значением 0
sum = sum + x1; //прибавляем первое слагаемое
sum = sum + x2; //прибавляем второе слагаемое
sum = sum + x3; //прибавляем третье слагаемое
return sum; //возвращаем результат
}
Посмотрите, насколько общее решение, позволяющее вычислить сумму элементов массива независимо от того, сколько в нем элементов элегантнее частного решения вычисления суммы трех элементов. Эта элегантность и красота решения достигается за счет использования такой структуры данных как массив.
А можно ли столь же просто вычислить сумму массива большей размерности? Оказывается, да. Вот соответствующий код для двумерного массива:
/// Сумма элементов двумерного массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>сумма его элементов</returns>
int Sum_Best(int[,] arr)
{
int n = arr.Length;
int sum = 0;
foreach (int item in arr)
sum += item;
return sum;
}
Здесь использован ранее не встречающийся оператор цикла foreach, который удобно применять при работе с массивами, поскольку он позволяет последовательно читать все элементы массива вне зависимости от размерности массива.
Следует заметить, что в отличие от цикла for в цикле foreach элементы массива можно только читать, но их нельзя изменять.
Приведу уже без дополнительных комментариев функции, вычисляющие произведение, максимальный и минимальный элементы массивов:
/// <summary>
/// Произведение элементов массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns>произведение его элементов</returns>
int Product(int[] arr)
{
int n = arr.Length;
int prod = 1;
for (int i = 0; i < n; i++)
prod *= arr[i];
return prod;
}
/// <summary>
/// Минимальный элемент массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns> его минимальный элемент</returns>
int Min(int[] arr)
{
int n = arr.Length;
int min = int.MaxValue;
for (int i = 0; i < n; i++)
if( arr[i] < min) min = arr[i];
return min;
}
/// <summary>
/// Максимальный элемент массива
/// </summary>
/// <param name="arr">массив</param>
/// <returns> его максимальный элемент</returns>
int Max(int[] arr)
{
int n = arr.Length;
int max = int.MinValue;
for (int i = 0; i < n; i++)
if (arr[i] > max) max = arr[i];
return max;
}
В проекте, сопровождающем лекцию, можно увидеть пример работы с двумерным массивом.
Переменные sum, prod, min, max, которые используются при вычислении соответствующих характеристик массива следует правильно инициализировать. В наших примерах кода используется рекомендованный способ инициализации, - сумму следует инициализировать нулем, произведение – единицей, минимум и максимум максимально возможным и минимально возможным значениями соответственно. Рекомендуемый способ не является единственно возможным.
Иногда для инициализации используется первый элемент массива. Это возможный прием, - во многих случаях такая инициализация корректно работает. Однако в ряде ситуаций она приводит к ошибкам, например, если исходный массив пуст или ищется максимальный элемент, удовлетворяющий некоторым дополнительным условиям.
При нахождении максимального элемента часто переменную max инициализируют отрицательным значением. Это корректно работает, если все элементы массива положительны, но в случаях, когда это предположение ошибочно, результат может быть не верным. Рекомендуемая нами схема инициализации корректно работает во всех ситуациях.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.