Raqamli texnologiyalar fakulteti dasturiy injiniring yo’nalishi



Download 1,57 Mb.
bet23/81
Sana23.06.2022
Hajmi1,57 Mb.
#695199
1   ...   19   20   21   22   23   24   25   26   ...   81
Bog'liq
Dasturiy injiniring Dasturlash 2-4

#ifndef ARRAYINT_H
#define ARRAYINT_H
#include
class ArrayInt
{
private:
int m_length;
int *m_data;
public:
ArrayInt():
m_length(0), m_data(nullptr)
{
m_length=0;
m_data=nullptr;
}
ArrayInt(int length):
m_length(length)
{
assert(length >= 0);
if (length > 0)
m_data = new int[length];
else
m_data = nullptr;
}
~ArrayInt()
{
delete[] m_data;
}
void erase()
{
delete[] m_data;
// Chiqishda osilgan ko'rsatgich bo'lmasligi uchun m_data ni nullptr ga o'rnating
m_data = nullptr;
m_length = 0;
}
int& operator[](int index)
{
assert(index >= 0 && index < m_length);
return m_data[index];
}
int getLength() { return m_length; }
};
#endif
Endi biz foydalanishimiz mumkin bo'lgan ArrayInt sinfiga egamiz. Biz ma'lum o'lchamdagi massivni ajratishimiz va elementlarning qiymatlarini olish yoki o'zgartirish uchun [] operatoridan foydalanishimiz mumkin.
Biroq, ArrayInt bilan biz qila olmaydigan yana bir nechta narsa bor. Bular massivning avtomatik oʻlchamini oʻzgartirish, elementlarni qoʻshish/oʻchirish va elementlarni saralash.
Birinchidan, massivni o'lchamini o'zgartirish mumkin bo'lsin. Buning uchun ikki xil funksiya yozamiz. Birinchi funktsiya qayta reallocate(), massiv hajmi o'zgartirilganda, u barcha mavjud elementlarni yo'q qiladi (bu tez). Ikkinchi funktsiya resize(), massiv o'lchamini o'zgartirganda, u barcha mavjud elementlarni saqlab qoladi (bu sekin).

// reallocate () funksiyasi massiv hajmini o'zgartiradi.


//Massiv ichidagi barcha mavjud elementlar yo'q qilinadi.
//Jarayon tez
void reallocate(int newLength)
{
// Massiv ichidagi barcha mavjud elementlarni olib tashlash
erase();
// Agar massivimiz bo'sh bo'lishi kerak bo'lsa, biz bu yerga qaytamiz
if (newLength <= 0)
return;
// Keyin biz yangi elementlarni tanlashimiz kerak
m_data = new int[newLength];
m_length = newLength;
}
// resize() funksiyasi massiv hajmini o'zgartiradi. Barcha mavjud elementlar saqlanib qoladi. Jarayon sekin
void resize(int newLength)
{
// Agar massiv kerakli uzunlikka ega bo'lsa, return bajaring
if (newLength == m_length)
return;
// Agar massivni bo'sh qilish kerak bo'lsa, buni bajaring va keyin return ni bajaring
if (newLength <= 0)
{
erase();
return;
}
// Endi, deylik newLength kamida bitta elementga ega. Quyidagi harakatlar ketma-ketligi amalga oshiriladi:
// 1. Yangi massivni ajrating.
// 2. Mavjud massivdagi elementlarni yangi tanlangan massivimizga nusxalash.
// 3. Eski massivni yo'q qiling va yangi massivga ishora qilish uchun m_data buyrug'ini bering.
int *data = new int[newLength];
// Keyin yangi massivga nusxalanadigan elementlar sonini aniqlashimiz kerak.
// Massivlarning kichikroq qismidagi qancha elementlar bo'lsa, shuncha ko'p elementni nusxalashimiz kerak
if (m_length > 0)
{
int elementsToCopy = (newLength > m_length) ? m_length : newLength;
// Elementlarni birma-bir nusxalash
for (int index=0; index < elementsToCopy ; ++index)
data[index] = m_data[index];
}
// Eski massivni o'chirib tashlang, chunki bizga endi kerak emas
delete[] m_data;
// Va eskisini o'rniga yangisini ishlating! E'tibor bering, m_data bizning yangi dinamik ravishda ajratilgan massivimiz ko'rsatgan manzilga ishora qiladi.
// Ma'lumotlar dinamik ravishda ajratilganligi sababli, ular ko'lamdan chiqib ketganda yo'q qilinmaydi
m_data = data;
m_length = newLength;
}

Ko’rib turganingizdek bu oson jarayon emas. Ko'pgina konteyner massivi sinflarining funksionalligi shu erda tugaydi. Ammo, agar siz elementlarni qo'shish / o'chirish qobiliyatini qanday amalga oshirishni ko'rishni istasangiz, endi biz buni ko'rib chiqamiz. Quyidagi ikkita algoritm resize() funksiyasiga juda o'xshash:


void insertBefore(int value, int index)


{
// O'tkazilgan indeksning to'g'riligini tekshirish
assert(index >= 0 && index <= m_length);
// Eski massivdan bir element kattaroq yangi massiv yarating
int *data = new int[m_length+1];
// Barcha elementlarni indeksgacha nusxalash
for (int before=0; before < index; ++before)
data[before] = m_data[before];
// Bizning yangi elementimizni yangi massivimizga joylashtiring
data [index] = value;
// Kiritilgan elementdan keyin barcha qiymatlarni nusxalash
for (int after=index; after < m_length; ++after)
data[after+1] = m_data[after];
// Eski massivni o'chiring va uning o'rniga yangi massivdan foydalaning
delete[] m_data;
m_data = data;
++m_length;
}
void remove(int index)
{
// O'tkazilgan indeksning to'g'riligini tekshiring
assert(index >= 0 && index < m_length);
// Agar bu massivning oxirgi elementi bo'lsa, u holda massivni bo'sh qilamiz va return
if (m_length == 1)
{
erase();
return;
}
// Eski massivimizdan bir element kichikroq yangi massiv yarating
int *data = new int[m_length-1];
// Barcha elementlarni indeksgacha nusxalash
for (int before=0; before < index; ++before)
data[before] = m_data[before];
// O'chirilgan elementdan keyin barcha qiymatlarni nusxalash
for (int after=index+1; after < m_length; ++after )
data[after-1] = m_data[after];
// Eski massivni o'chiring va uning o'rniga yangi massivdan foydalaning
delete[] m_data;
m_data = data;
--m_length;
}
// Qulaylik uchun bir nechta qo'shimcha funktsiyalar
void insertAtBeginning(int value) { insertBefore(value, 0); }
void insertAtEnd(int value) { insertBefore(value, m_length); }

Mana bizning ArrayInt konteyner sinfimiz.


ArrayInt.h:


#ifndef ARRAYINT_H


#define ARRAYINT_H
#include // для assert()
class ArrayInt
{
private:
int m_length;
int *m_data;
public:
ArrayInt():
m_length(0), m_data(nullptr)
{
}
ArrayInt(int length):
m_length(length)
{
assert(length >= 0);
if (length > 0)
m_data = new int[length];
else
m_data = nullptr;
}
~ArrayInt()
{
delete[] m_data;
}
void erase()
{
delete[] m_data;
// Здесь нужно указать m_data значение nullptr, чтобы на выходе не было висячего указателя
m_data = nullptr;
m_length = 0;
}
int& operator[](int index)
{
assert(index >= 0 && index < m_length);
return m_data[index];
}
// Функция reallocate() изменяет размер массива. Все существующие элементы внутри массива будут уничтожены. Процесс быстрый
void reallocate(int newLength)
{
// Удаляем все существующие элементы внутри массива
erase();
// Если наш массив должен быть пустым, то выполняем возврат здесь
if (newLength <= 0)
return;
// Затем выделяем новые элементы
m_data = new int[newLength];
m_length = newLength;
}
// Функция resize() изменяет размер массива. Все существующие элементы сохраняются. Процесс медленный
void resize(int newLength)
{
// Если массив нужной длины, то выполняем return
if (newLength == m_length)
return;
// Если нужно сделать массив пустым, то делаем это и затем выполняем return
if (newLength <= 0)
{
erase();
return;
}
// Теперь предположим, что newLength состоит, по крайней мере, из одного элемента. Выполняется следующий алгоритм действий:
// 1. Выделяем новый массив.
// 2. Копируем элементы из существующего массива в наш только что выделенный массив.
// 3. Уничтожаем старый массив и даем команду m_data указывать на новый массив.
// Выделяем новый массив
int *data = new int[newLength];
// Затем нам нужно разобраться с количеством копируемых элементов в новый массив.
// Нам нужно скопировать столько элементов, сколько их есть в меньшем из массивов
if (m_length > 0)
{
int elementsToCopy = (newLength > m_length) ? m_length : newLength;
// Поочередно копируем элементы
for (int index=0; index < elementsToCopy ; ++index)
data[index] = m_data[index];
}
// Удаляем старый массив, так как он нам уже не нужен
delete[] m_data;
// И используем вместо старого массива новый! Обратите внимание, m_data указывает на тот же адрес, на который указывает наш новый динамически выделенный массив.
// Поскольку данные были динамически выделены, то они не будут уничтожены, когда выйдут из области видимости
m_data = data;
m_length = newLength;
}
void insertBefore(int value, int index)
{
// Проверка корректности передаваемого индекса
assert(index >= 0 && index <= m_length);
// Создаем новый массив на один элемент больше старого массива
int *data = new int[m_length+1];
// Копируем все элементы аж до index
for (int before=0; before < index; ++before)
data [before] = m_data[before];
// Вставляем наш новый элемент в наш новый массив
data [index] = value;
// Копируем все значения после вставляемого элемента
for (int after=index; after < m_length; ++after)
data[after+1] = m_data[after];
// Удаляем старый массив и используем вместо него новый массив
delete[] m_data;
m_data = data;
++m_length;
}
void remove(int index)
{
// Проверка на корректность передаваемого индекса
assert(index >= 0 && index < m_length);
// Если это последний элемент массива, то делаем массив пустым и выполняем return
if (m_length == 1)
{
erase();
return;
}
// Cоздаем новый массив на один элемент меньше нашего старого массива
int *data = new int[m_length-1];
// Копируем все элементы аж до index
for (int before=0; before < index; ++before)
data[before] = m_data[before];
// Копируем все значения после удаляемого элемента
for (int after=index+1; after < m_length; ++after )
data[after-1] = m_data[after];
// Удаляем старый массив и используем вместо него новый массив
delete[] m_data;
m_data = data;
--m_length;
}
// Несколько дополнительных функций просто для удобства
void insertAtBeginning(int value) { insertBefore(value, 0); }
void insertAtEnd(int value) { insertBefore(value, m_length); }
int getLength() { return m_length; }
};
#endif

Edi dasturni testdan o’tkazamiz


#include


#include "ArrayInt.h"
int main()
{
// Объявляем массив с 10 элементами
ArrayInt array(10);
// Заполняем массив числами от 1 до 10
for (int i=0; i<10; i++)
array[i] = i+1;
// Изменяем размер массива до 7 элементов
array.resize(7);
// Вставляем число 15 перед элементом с индексом 4
array.insertBefore(15, 4);
// Удаляем элемент с индексом 5
array.remove(5);
// Добавляем числа 35 и 50 в конец и в начало
array.insertAtEnd(35);
array.insertAtBeginning(50);
// Выводим все элементы массива
for (int j=0; jstd::cout << array[j] << " ";
return 0;
}

Natija:

50 1 2 3 4 15 6 7 35

Konteyner sinflarini yozish biroz qiyin bo'lishi mumkin bo'lsa-da, yaxshi xabar shundaki, ularni faqat bir marta yozishingiz kerak. Konteyner klassi ishga tushirilgandan so'ng, uni istalgan joyda qo'shimcha kodlash/kodlash harakatlarisiz qayta ishlatishingiz mumkin.


Shuni ham ta'kidlash joizki, ArrayInt konteyner sinfimiz asosiy ma'lumotlar turini (int) o'z ichiga olsa ham, biz maxsus ma'lumotlar turidan ham osonlikcha foydalanishimiz mumkin.


Eslatma: Agar C ++ standart kutubxonasi sinfi sizning ehtiyojlaringizga to'liq javob bersa, o'z konteyner sinfingizni yozish o'rniga undan foydalaning. Masalan, ArrayInt o'rniga std :: vektor dan foydalanish yaxshidir, chunki std :: vektor ilovasi ko'p yillar davomida sinovdan o'tgan/tasdiqlangan, samarali va C sinfidagi boshqa sinflar bilan yaxshi ishlaydi. ++ Standart kutubxona. Ammo C ++ standart kutubxonasidan sinflardan foydalanish har doim ham imkoni bo'lmasligi mumkinligi sababli, siz o'zingizning konteyner sinflaringizni qanday yaratishni allaqachon bilasiz.




24-25-MA’RUZA. STANDART SHABLONLAR SINFIGA KIRISH (KOLLEKSIYALAR SINFI),ASOSIY TUSHUNCHALAR. KONTEYNER SINFLAR TIPLARI, KONTEYNERLAR ADAPTERLARI. ALGORITMLAR VA ULARNI KONTEYNER SINFLAR BILAN ISHLATISH USULLARI





Download 1,57 Mb.

Do'stlaringiz bilan baham:
1   ...   19   20   21   22   23   24   25   26   ...   81




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish