- •Мгул, пм-21, 4 семестр, 2012 год
- •Контрольная работа №2
- •Class Command (Calculator) (лаб. Раб. №3)
- •Задание * (лаб. Раб. №4)
- •Дать описание классов, созданных в файлах: Array.H, Array.Cpp
- •12.1. Исходный код файла Array.H (лаб. Раб. №5)
- •12.2. Исходный код файла Array.Cpp (лаб. Раб. №6)
- •Выполнить задание (лаб. Раб. №7)
- •Дать описание классов проекта Kolobok («Колобок») (лаб. Раб. №8)
- •В проект Kolobok добавить персонаж RedCup («Красная шапочка») (лаб. Раб. №9)
12.2. Исходный код файла Array.Cpp (лаб. Раб. №6)
#include <Windows.h>
#include "Array.h"
const pvoid Array::DUMMY = NULL;
Array::Array(uint Delta, uint Count) : data(NULL), length(0), userlen(Count), delta(Delta)
{
if (Count) this->changeSize(Count);
}
Array &Array::Insert(pvoid whatToAdd, uint whereAdd) {
if (userlen == length)
changeSize(length + delta);
userlen++;
if (whereAdd >= userlen)
throw "Нельзя вставлять за пределами массива";
if (whereAdd < userlen - 1)
memmove(&data[whereAdd + 1], &data[whereAdd], (userlen - whereAdd - 1) << 2);
data[whereAdd] = whatToAdd;
return *this;
}
int Array::Add(pvoid whatToAdd)
{
if (!whatToAdd)
throw "Array::Add - добавление в массив NULL. Запрещено";
uint i;
for (i = 0; i < userlen; i++)
if (!data[i]) {
data[i] = whatToAdd;
return i;
}
*this << whatToAdd;
return userlen - 1;
}
Array &Array::operator << (pvoid whatToAdd)
{
if (userlen == length)
changeSize(length + delta);
data[userlen++] = whatToAdd;
return *this;
}
Array &Array::operator >> (pvoid *whatToGet)
{
*whatToGet = (userlen ? data[--userlen] : DUMMY);
if (length > userlen + delta)
changeSize(length - delta >= 0 ? length - delta : 0);
return *this;
}
void Array::SetSize(uint newSize) {
changeSize(newSize);
userlen = length;
}
void Array::changeSize(uint newSize)
{
if (newSize == length) return;
if (newSize < 0) throw "Задан отрицательный размер массива";
void **temp = (newSize ? new pvoid[newSize] : NULL);
if (data) {
if (temp)
memcpy(temp, data, min(newSize, userlen) * sizeof(pvoid));
delete []data;
}
data = temp;
length = newSize;
}
void Array::Remove(uint n) {
if (n >= userlen)
throw "Из массива извлекается элемент с большим номером. Выход за границы массива.";
userlen--;
if (userlen + delta < length) {
length -= delta;
void **temp;
if (length > 0) temp = new pvoid[length];
else temp = NULL, length = 0;
memcpy(temp, data, 4 * n);
memcpy(temp + n, data + n + 1, 4 * (userlen - n));
delete []data;
data = temp;
}
else
memmove(data + n, data + n + 1, 4 * (userlen - n));
}
void Array::DelNULL() {
uint N = 0;
for (uint i = 0; i < userlen; i++)
N += data[i] != NULL;
void **temp = (N ? new pvoid[N] : NULL);
if (data && temp)
for (uint i = 0, j = 0; i < userlen; i++)
if (data[i])
temp[j++] = data[i];
if (data)
delete []data;
data = temp;
length = userlen = N;
}
pvoid &Array::operator [](uint index)
{
if (index >= userlen)
throw "Обращение к элементу массива: выход за границы массива.";
return data[index];
}
void Array::Sort(bool (*comp)(const void *o1, const void *o2)) {
for (uint i = 1; i < userlen; i++) {
for (uint j = i; j > 0 && comp(data[j], data[j-1]); j--) {
pvoid register temp = data[j];
data[j] = data[j-1];
data[j-1] = temp;
}
}
}
void Array::FastSort(bool (*comp)(const void *o1, const void *o2)) {
void *Temp;
for (uint i = 1; i < userlen; i++) {
Temp = data[i];
if (comp(data[i-1], data[i]))
continue;
uint a = 0, b = i, m;
while (a < b) {
m = (a + b) >> 1;
if (comp(data[m], Temp))
a = m + 1;
else
b = m;
}
memmove(data+a+1, data+a, (i - a) * 4);
data[a] = Temp;
}
}
int Array::Find(const void *o, bool (*comp)(const void *o1, const void *o2)) {
for (uint i = 0; i < userlen; i++)
if (comp(data[i], o))
return i;
return -1;
}
int Array::FindInSorted(const void *o, int (*comp)(const void *o1, const void *o2)) {
unsigned int a = 0, b = userlen, m;
int rez = 1;
while (a < b) {
m = (a + b) >> 1;
rez = comp(data[m], o);
if (rez > 0)
a = m + 1;
else if (rez < 0)
b = m;
else
b = m;
}
return (a < userlen && comp(data[a], o) == 0) ? a : -1;
}
Array::~Array() {
if (data)
delete []data;
}