4
Page 1 of 4 ლაბორატორიული მეცადინება 8 განსახილველი საკითხები: ამოცანა /ჯაჭვებიანი ჰეშ-ცხრილის შექმნა და გასინჯვა/ ჯაჭვებიანი ჰეშ-ცხრილის კლასი >>> პროგრამა-დრაივერი >>> სავარჯიშოები >>> ამოცანა: შევქმნათ ჯაჭვებიანი ჰეშ-ცხრილის კლასი, რომელსაც ექნება ელემენტის ჩამატების, წაშლის, და ამ ცხრილში მოცემული ელემენტის მოძებნის ფუნქციები. მთავარ ფუნქციაში: შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც ელემენტების ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. ჩავწეროთ მასში 77 და შემდეგ მიმდევრობით გასაღებები 0,1,...,24. დავბეჭდოთ ცხრილი და დავბეჭდოთ მისი ზომა. შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც ელემენტების ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. ჩავწეროთ მასში 77 და შემდეგ მიმდევრობით გასაღებები 0,1,...,44. დავბეჭდოთ ცხრილი, მოვძებნოთ ცხრილში ელემენტები 777 და 21. დავბეჭდოთ ცხრილის ზომა. წავშალოთ 21. დინამიკურად შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც ელემენტების ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. მიმდევრობით ჩავამატოთ გასაღებები 0,1,...,14. დავბეჭდოთ ცხრილი და შემდეგ წავშალოთ. ამოხსნა: <<< ჯაჭვებიანი ჰეშ-ცხრილის კლასი ამჯერად ჩვენ არ ვქმნით ტემპლიტიან კლასს, მაგრამ ადვილი გადასაკეთებელი რომ იყოს, კლასს არ გავყოფთ ორ ფაილად (ტემპლიტიანი კლასის გაყოფა არ შეიძლება ორ ფაილად). ასე რომ, გვაქვს მხოლოდ ერთი header ფაილი: #pragma once #include<iostream> #include<list> #include<algorithm> #include<iterator> using namespace std; class ChainedHashTable { private: list<int>* hTable; int (*fPtr)(int, int); int size; int capacity; public: ChainedHashTable(void); ~ChainedHashTable(void); ChainedHashTable(int m, int hashFunc(int, int)); void insert(int item); int getSize(void);

Lab8 2014 chained_hashtable

Embed Size (px)

Citation preview

Page 1: Lab8 2014 chained_hashtable

Page 1 of 4

ლაბორატორიული მეცადინება 8

განსახილველი საკითხები:

ამოცანა /ჯაჭვებიანი ჰეშ-ცხრილის შექმნა და გასინჯვა/

ჯაჭვებიანი ჰეშ-ცხრილის კლასი >>>

პროგრამა-დრაივერი >>>

სავარჯიშოები >>>

ამოცანა: შევქმნათ ჯაჭვებიანი ჰეშ-ცხრილის კლასი, რომელსაც ექნება ელემენტის ჩამატების,

წაშლის, და ამ ცხრილში მოცემული ელემენტის მოძებნის ფუნქციები.

მთავარ ფუნქციაში:

შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც ელემენტების

ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. ჩავწეროთ მასში 77 და შემდეგ

მიმდევრობით გასაღებები 0,1,...,24. დავბეჭდოთ ცხრილი და დავბეჭდოთ მისი ზომა.

შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც ელემენტების

ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. ჩავწეროთ მასში 77 და შემდეგ

მიმდევრობით გასაღებები 0,1,...,44. დავბეჭდოთ ცხრილი, მოვძებნოთ ცხრილში

ელემენტები 777 და 21. დავბეჭდოთ ცხრილის ზომა. წავშალოთ 21.

დინამიკურად შევქმნათ ამ კლასის ობიექტი მთელი რიცხვების შესანახად, რომელიც

ელემენტების ჩასამატებლად გამოიყენებს გაყოფის ჰეშ-ფუნქციას. მიმდევრობით

ჩავამატოთ გასაღებები 0,1,...,14. დავბეჭდოთ ცხრილი და შემდეგ წავშალოთ.

ამოხსნა:

<<< ჯაჭვებიანი ჰეშ-ცხრილის კლასი

ამჯერად ჩვენ არ ვქმნით ტემპლიტიან კლასს, მაგრამ ადვილი გადასაკეთებელი რომ იყოს,

კლასს არ გავყოფთ ორ ფაილად (ტემპლიტიანი კლასის გაყოფა არ შეიძლება ორ ფაილად).

ასე რომ, გვაქვს მხოლოდ ერთი header ფაილი:

#pragma once #include<iostream> #include<list> #include<algorithm> #include<iterator> using namespace std; class ChainedHashTable { private: list<int>* hTable; int (*fPtr)(int, int); int size; int capacity; public: ChainedHashTable(void); ~ChainedHashTable(void); ChainedHashTable(int m, int hashFunc(int, int)); void insert(int item); int getSize(void);

Page 2: Lab8 2014 chained_hashtable

Page 2 of 4

int getCapacity(void); template<typename BidirectionalIterator> list<int>* search(int item, BidirectionalIterator &it); void erase(int item); void show(void); }; ChainedHashTable::ChainedHashTable(int m, int hashFunc(int, int)) { hTable = new list<int>[m]; capacity=m; fPtr = hashFunc; size=0; } ChainedHashTable::~ChainedHashTable(void) { for(int i=0; i<capacity; i++) while( hTable[i].size()!=0 ) hTable[i].pop_front(); delete [] hTable; hTable = NULL; } void ChainedHashTable::insert(int item) { int i = (*fPtr)(item, capacity); hTable[i].push_front(item); size++; } void ChainedHashTable::show(void) { ostream_iterator<int> out(cout, "\t"); for(int i=0; i<capacity; i++) { copy( hTable[i].begin(),hTable[i].end(), out); cout << endl; } } int ChainedHashTable::getSize(void) { return size; } int ChainedHashTable::getCapacity(void) { return capacity; } template<typename BidirectionalIterator> list<int>* ChainedHashTable::search(int item,BidirectionalIterator &it) { int i = (*fPtr)(item, capacity); it = find(hTable[i].begin(), hTable[i].end(),item); return &hTable[i]; } void ChainedHashTable::erase(int item) { list<int>::iterator it; list<int>* lstP; lstP = search(item,it); if(it != lstP->end()) lstP->erase(it);

Page 3: Lab8 2014 chained_hashtable

Page 3 of 4

size--; }

შევნიშნოთ, რომ ეს არაა სრულყოფილი კლასი, რადგან მხოლოდ მთელი რიცხვების შენახვის

საშუალებაა გათვალისწინებული. აგრეთვე, არაა გადატვირთული გამოტანის ოპერატორი,

მინიჭების ოპერატორი და ასლის გამკეთებელი კოსტრუქტორი (როდესაც მეხსიერების

დინამიკური გამოყოფა ხდება, ამათი, კონსტრუქტორის და დესტრუქტორის არსებობა

აუცილებელია).

აქ არის იგივე საინტერესო მომენტები, რაც შეგვხვდა წინა მეცადინეობაზე. კერძოდ, კლასის

ერთი კერძო ველი გათვალისწინებულია ფუნქციის დასამახსოვრებლად.

არის განსხვავებული მომენტი: ჩვენ გამოვიყენეთ მრავალგანზომილებიანი (შერერული)

კონტეინერი.

<<< პროგრამა დრაივერი:

#include "ChainedHashTable.h" int hashByMod(int key, int M) { return key % M; } int hashByMultiply(int key, int M) { const double A=(sqrt(5.0)-1)/2; return int(M*(A*key-floor(A*key))); } int main() { ChainedHashTable hash(11,hashByMod); hash.insert(77); for(int i=0; i<25; i++) hash.insert( i ); cout << "Hash table \"hash\":" << endl; hash.show(); cout << "hash.size()=" <<hash.getSize() <<endl<<endl;

int k = 21; list<int>::iterator it; list<int>* lstP; lstP = hash.search(k,it); if(it != lstP->end()) cout << "Found k =" << *it << endl;

else cout << k << " Not found!" << endl;

k = 777; lstP = hash.search(k,it);

if(it != lstP->end()) cout << "In hash found k =" << *it << endl;

else cout << k << " Not found!" << endl << endl;

Page 4: Lab8 2014 chained_hashtable

Page 4 of 4

ChainedHashTable hash1(11,hashByMultiply); hash1.insert(77); for(int i=0; i<45; i++) hash1.insert( i ); cout << endl <<"Hash table \"hash\":"<< endl;

hash1.show();

k = 21; lstP = hash1.search(k,it);

if(it != lstP->end()) cout<<endl<<"In hash1 found k ="<<*it<<

endl; else cout << k << " Not found!" << endl << endl; hash1.erase(k); cout << "Hash table \"hash\" after deleting "

<< k << endl; hash1.show();

ChainedHashTable* htAdress = new ChainedHashTable(3,hashByMod);

for(int i=0; i<15; i++) htAdress->insert( i ); cout << "Hash table \"*htAdress\":" << endl; htAdress->show(); delete htAdress; htAdress = NULL; return 0; }

მარჯვენა ცხრილი წარმოადგენს პროგრამის მუშაობის

შედეგს .

<<< სავარჯიშო

1. გააკეთეთ ტემპლიტიანი კლასი იგივე

მიზნისთვის. ყურადღება მიაქციეთ ჰეშ-

ფუნქციებს.

Hash table "hash": 22 11 0 77 23 12 1 24 13 2 14 3 15 4 16 5 17 6 18 7 19 8 20 9 21 10 hash.size()=26 Found k =21 777 Not found! Hash table "hash": 34 26 13 5 0 39 31 18 10 44 36 23 15 2 41 28 20 7 33 25 12 38 30 17 4 43 35 22 9 1 77 40 27 14 6 32 19 11 37 24 16 3 42 29 21 8 In hash1 found k =21 Hash table "hash" after deleting 21 34 26 13 5 0 39 31 18 10 44 36 23 15 2 41 28 20 7 33 25 12 38 30 17 4 43 35 22 9 1 77 40 27 14 6 32 19 11 37 24 16 3 42 29 8 Hash table "*htAdress": 12 9 6 3 0 13 10 7 4 1 14 11 8 5 2 Press any key to continue . . .