Читайте также:
|
|
Информатика. Предмет информатики. Основные задачи информатики. 2
Устройства ввода/вывода данных, их разновидности и основные характеристики 2
Основы машинной графики. Системы компьютерной графики и анимации. 16
Электронные презентации. 21
Информационная модель объекта. 22
Этапы разработки программного обеспечения. 24
Эволюция языков программирования. Классификация языков программирования 25
Назначение и основы использования систем искусственного интеллекта; базы знаний, экспертные системы, искусственный интеллект. 32
Программы для работы в сети Интернет. 37
Классификация и характеристики компьютерных вирусов. 38
Методы защиты от компьютерных вирусов. 42
Список используемых источников. 48
Оглавление. 49
КУРСОВА РОБОТА
З дисципліни: Інформатика
Виконав студент 2-курсу ІЗДН
Спеціальність: 6.050802
“Електронні пристрої та системи”
Погорєлов Михайло Геннадійович
Зал.кн. №18.0504
Р.
Зміст
Задание………………………………………………………………………………………………3
Процедура слияния…………………………………………………………………………………3
Сортировка слиянием………………………………………………………………………………4
Лістинг програми……………………………………………………………………………………6
Задание: Ввести массивы А и В. В массив С перенести те четные элементы массива А, левее которых стоят элементы с нечетным значением. Также в массив С перенести элементы В, который по значению ближе всех к (min+max)/2? где min – значение минимального элемента массива В, а max - значение максимального элемента массива В. Массивы А,В и С отсортировать по возрастанию, используя сортировку методом слияния.
Процедура слияния
Допустим, у нас есть два отсортированных массива A и B размерами и
соответственно, и мы хотим объединить их элементы в один большой отсортированный массив C размером
. Для этого можно применить процедуру слияния, суть которой заключается в повторяющемся «отделении» элемента, наименьшего из двух имеющихся в началах исходных массивов, и присоединении этого элемента к концу результирующего массива. Элементы мы переносим до тех пор, пока один из исходных массивов не закончится. После этого оставшийся «хвост» одного из входных массивов дописывается в конец результирующего массива. Пример работы процедуры показан на рисунке:
Рис. 1. Пример работы процедуры слияния
Алгоритм слияния формально можно записать следующим образом:
![]() | (1) |
Для обеспечения стабильности алгоритма сортировки нужно, чтобы в случае равенства элементов тот элемент, что идёт раньше во входном массиве, попадал в результирующий массив в первую очередь. Мы увидим далее, что если два элемента попали в разные массивы (A и B), то тот элемент, что шёл раньше, попадёт в массив A. Следовательно, в случае равенства элемент из массива A должен иметь приоритет. Поэтому в алгоритме стои́т знак вместо < при сравнении элементов.
Недостатком представленного алгоритма является необходимость дописывать оставшийся кусок, из-за чего при дальнейших модификациях алгоритма нам придётся писать много повторяющегося кода. Чтобы этого избежать, будем использовать чуть менее эффективный, но более короткий алгоритм, в котором копирование «хвоста» встроено в основной цикл:
![]() | (2) |
Время работы процедуры слияния составляет .
Реализация процедуры слияния на языке программирования C++ представлена в листинге 1.
template<class T> void Merge ( T const *const A, int const nA,
T const *const B, int const nB,
T *const C )
{ //Выполнить слияние массива A, содержащего nA элементов,
// и массива B, содержащего nB элементов.
// Результат записать в массив C.
int a ( 0 ), b ( 0 ); //Номера текущих элементов в массивах A и B
while ( a+b < nA+nB ) //Пока остались элементы в массивах
{
if (( b>=nB ) || (( a<nA ) && ( A [ a ] <=B [ b ])))
{ //Копирую элемент из массива A
C [ a+b ] = A [ a ];
++a;
} else { //Копирую элемент из массива B
C [ a+b ] = B [ b ];
++b;
}
}
}
Листинг 1. Компактная (не самая быстрая) реализация процедуры слияния
Сортировка слиянием
Процедура слияния требует два отсортированных массива. Заметив, что массив из одного элемента по определению является отсортированным, мы можем осуществить сортировку следующим образом:
1. разбить имеющиеся элементы массива на пары и осуществить слияние элементов каждой пары, получив отсортированные цепочки длины 2 (кроме, быть может, одного элемента, для которого не нашлось пары);
2. разбить имеющиеся отсортированные цепочки на пары, и осуществить слияние цепочек каждой пары;
3. если число отсортированных цепочек больше единицы, перейти к шагу 2.
Проще всего формализовать этот алгоритм рекурсивным способом (в следующем разделе мы реализуем этот алгоритм итерационным способом). Функция сортирует участок массива от элемента с номером a до элемента с номером b:
![]() | (3) |
Поскольку функция сортирует лишь часть массива, то при слиянии двух фрагментов ей не остаётся ничего, кроме как выделять временный буфер для результата слияния, а затем копировать данные обратно:
template<class T> void MergeSort ( T *const A, int const n )
{ //Отсортировать массив A, содержащий n элементов
if ( n < 2 ) return; //Сортировка не нужна
if ( n == 2 ) //Два элемента проще поменять местами,
{ // если нужно, чем делать слияние
if ( A [ 0 ] > A [ 1 ]) { T const t ( A [ 0 ]); A [ 0 ] =A [ 1 ]; A [ 1 ] =t; }
return;
}
MergeSort ( A, n/2 ); //Сортируем первую половину
MergeSort ( A+n/2, n-n/2 ); //Сортируем вторую половину
T *const B ( new T [ n ]); //Сюда запишем результат слияния
Merge ( A,n/2, A+n/2,n-n/2, B ); //Слияние половин
//Копирование результата слияния в исходный массив:
for ( int i ( 0 ); i<n; ++i ) A [ i ] =B [ i ];
delete [ n ] B; //Удаляем временный буфер
}
Листинг 2. Реализация сортировки слиянием
Время работы сортировки слиянием составляет . Пример работы процедуры показан на рисунке:
Рис. 2. Пример работы рекурсивного алгоритма сортировки слиянием
Лістинг програми
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
int merge (int *m1, int m1n, int *m2, int m2n, int *m3) {
int a(0), b(0);
while (a+b < m1n+m2n)
{
if((b>=m2n) || ((a<m1n) && (m1[a]<=m2[b])))
{ //Копирую элемент из массива A
m3[a+b] = m1[a];
++a;
} else { //Копирую элемент из массива B
m3[a+b] = m2[b];
++b;
}
}
}
void mergeSort (int *massiv, int n) {
if (n < 2)
return;
if (n == 2) {
if(massiv[0] > massiv[1])
{
swap (massiv[0], massiv[1]);
return;
}
}
mergeSort (massiv, n/2);
mergeSort (massiv+n/2, n-n/2);
int *TMP = new int[n];
merge(massiv,n/2,massiv+n/2,n-n/2,TMP);
for(int i(0); i<n; ++i) massiv[i]=TMP[i];
delete[n] TMP; //Удаляем временный буфер
return;
}
int main(int argc, char* argv[])
{
// Объявляем переменные размеров массивов
int An;
int Bn;
// Запрашиваем значения размера для каждого массива у пользователя
cout<<"\nRazmer massiva A:\n";
cin>>An;
cout<<"\nRazmer massiva B:\n";
cin>>Bn;
// Создаем массивы с указаными размерами (Выделяем память под них)
int *A = new int[An];
int *B = new int[Bn];
// Заполняем массивы случайными числами
for (int i = 0; i<An; i++)
{
A[i] = rand() % 100 + 1;
}
for (int i = 0; i<Bn; i++)
{
B[i] = rand() % 100 + 1;
}
// Отобразим заполненные массивы
cout<<"\nA:\n";
for (int i = 0; i<An; i++)
{
cout<<i<<"="<<A[i]<<"\n";
}
cout<<"\nB:\n";
for (int i = 0; i<Bn; i++)
{
cout<<i<<"="<<B[i]<<"\n";
}
// Посчитаем колличество нечетных значений в массиве для переноса в новый массив
int count = 0;
for (int i = 0; i<An; i++)
{
/*
Если остаток от деления на 2 равен 0 то мы имеем дело с четным индексом,
И если значение этого елемента не является четным по противоположному
принципу, то считаем этот елемент так как он попадает под условие поставленной
задачи. Его и будем переносить
*/
if (i%2==0 && A[i]%2!=0)
{
count++;
}
}
// Ищем максимально близкое по значению к (min+max)/2 в массиве В
// Сначала найдем минимальное и максимальное значение в массиве
// Сначала примем за минимальное первый елемент массива
int minB = B[0];
for (int i = 0; i<Bn; i++)
{
// И если он окажется больше какого-то значения в массиве
if (B[i] < minB)
{
// Мы примем это значение как минимальное
minB = B[i];
}
}
// По аналогии найдем максимальное значение
int maxB = B[0];
for (int i = 0; i<Bn; i++)
{
// И если он окажется больше какого-то значения в массиве
if (B[i] > maxB)
{
// Мы примем это значение как минимальное
maxB = B[i];
}
}
// Теперь посчитаем чему будет равно наче условие (min+max)/2
int uslovie;
uslovie = (minB + maxB)/2;
cout<<"\nUslovioe ravno: "<<uslovie<<"\n\n";
cout<<"\n_____________________________";
// Теперь можно найти максимально близкое к этому значение в массиве В
// Принцип схож с поиском крайних значений
int blizkoeB = B[0];
for (int i = 0; i<Bn; i++)
{
// Только здесь мы сравниваем абсолютную разницу между значением елемента
// и услоивем с абсолютной разницей между условием и значением предыдущего
// максимально подходящего эелемента, по умолчанию выбираем первый элемент
if (abs(uslovie-B[i]) < abs(uslovie - blizkoeB))
{
blizkoeB = B[i];
}
}
// Теперь заполним массив С нашими значениями
// Размер увеличим на 1 так как к перенесенным добавляем еще максимально
// похожее к условию (min+max)/2 значение из массива В
count++;
int *C = new int[count];
// Добавим близкое первым елементом нового массива
C[0] = blizkoeB;
// Заполняем значениями из массива А
int j = 1;
int x = 0;
for (int i = 0; i<An; i++)
{
/*
Если остаток от деления на 2 равен 0 то мы имеем дело с четным индексом,
И если значение этого елемента не является четным по противоположному
принципу, то считаем этот елемент так как он попадает под условие поставленной
задачи. Его и будем переносить
*/
if (i%2==0 && A[i]%2!=0)
{
// Четные индексы с нечетными значениями в новый массив
C[j]=A[i];
j++;
}
else {
// Остальные сгруппируем в начале массива
A[x]=A[i];
x++;
}
}
// Уменьшим размер массива до колличества оставшихся в нём елементов
An=x;
// Отобразим новые массив
cout<<"\nA:\n";
for (int i = 0; i<An; i++)
{
cout<<i<<"="<<A[i]<<"\n";
}
cout<<"\nC:\n";
for (int i = 0; i<count; i++)
{
cout<<i<<"="<<C[i]<<"\n";
}
cout<<"\n_____________________________\n";
// Отсортируем массивы
mergeSort (A, An);
mergeSort (B, Bn);
mergeSort (C, count);
// Отобразим новые массив
cout<<"\nA:\n";
for (int i = 0; i<An; i++)
{
cout<<i<<"="<<A[i]<<"\n";
}
cout<<"\nB:\n";
for (int i = 0; i<Bn; i++)
{
cout<<i<<"="<<B[i]<<"\n";
}
cout<<"\nC:\n";
for (int i = 0; i<count; i++)
{
cout<<i<<"="<<C[i]<<"\n";
}
cout<<"\n_____________________________\n";
getch();
return 0;
}
Идеология абсолютной монархии в
Дата добавления: 2014-12-15; просмотров: 122 | Поможем написать вашу работу | Нарушение авторских прав |