You are on page 1of 12

ლაბ.3 ასოციაციური კონტეინერები ასახვა და მულტიასახვა.

სასრული განსაზღვრის
არის და მნიშვნელობათა სიმრავლის მქონე ფუნქციების რეალიზაცია
• Map-ის და Multimap-ის ძირითადი თვისებები და ფუნქციები
• ფუნქციების წარმოდგენა
• მაგალითები
• სავარჯიშოები

map და multimap კონტეინერები

map და multimap არიან ასოციაციური კონტეინერები, რომლებიც ინახავენ და


ალაგებენ მონაცემთა წყვილებს.

• განაცხადი ასახვაზე და მულტიასახვაზე კეთდება შემდეგნაირად:

map<data type ,data type>map name multimap< data type ,data type >map name,
მონაცემის ტიპი შეიძლება იყოს ნებისმიერი: int, float, char, string,…

• map-ის და multimap-ის გამოსაყენებლად საჭიროა შემდეგი თავსართის ჩართვა:


#include<map>

• გაჩუმების პრინციპით, ასახვაში და მულტიასახვაში ელემენტები ლაგდება


ზრდადობით „გასაღების“ მიხედვით. თუ გვინდა დავალაგოთ კლებადობით,
ასახვაზე და მულტიასახვაზე განაცხადი უნდა შემდეგნაირად გავაკეთოთ:

map<data type ,data type, greater<>>map name


multimap<data type ,data type, greater<>>map name,
ამასთან, უნდა დაემატოს თავსართი #include<functional>.

map -ის ძირითადი თვისებები და ფუნქციები

o map-ის ელემენტები არიან წყვილები. (წყვილის პირველი ელემენტი არის


„გასაღები“, ხოლო მეორე ელემენტი-„მნიშვნელობა“). ამ წყვილების ძებნის
ბინარული ხის აგება და ელემენტების დალაგება ხდება „გასაღების“
მიხედვით, და გასაღების შესაბამისი „მნიშვნელობა“, უბრალოდ, უერთდება
გასაღებს.
o map-ის ელემენტებს „გასაღების“ მიხედვით უნიკალური მნიშვნელობა აქვთ;

1
o map-ში გადატვირთულია [] და at ოპერატორები. [] ოპერატორის საშუალებით
შესაძლებელია ასახვის ელემენტის მნიშვნელობის შეცვლა.
o map-ის ელემენტები არ არის ინდექსირებული, მათზე წვდომა ხორციელდება
იტერატორის საშუალებით.

map -ის ძირითადი ფუნქციები

begin() აბრუნებს პირველი ელემენტის იტერატორს


end() აბრუნებს ასახვის დასასრულის იტერატორს, რომელიც
ბოლო ელემენტის თეორიულად მომდევნო ელემენტის
მისამართია
size() აბრუნებს ელემენტების რაოდენობას ასახვაში
max_size() აბრუნებს ელემენტების მაქსიმალურად შესაძლო
რაოდენობას ასახვაში
empty() აბრუნებს “true”(1)-ს, თუ ასახვა ცარიელია, წინააღმდეგ
შემთხვევაში, აბრუნებს “false”(0)-ს.
pair.insert (key, ამატებს ახალ ელემენტს(წყვილს) ასახვას.
value)
emplace(key, value) ამატებს ახალ ელემენტს(წყვილს) ასახვას.
erase(const x) შლის “x” გასაღების მქონე ელემენტს ასახვიდან.
erase(iterator შლის იტერატორით მითითებულ პოზიციაზე მდგომ
position) ელემენტს ასახვიდან და აბრუნებს მისი მომდევნო
ელემენტის იტერატორს.
clear() შლის ყველა ელემენტს სიმრავლიდან.
find(const x) აბრუნებს “x” გასაღების მქონე წყვილის შესაბამისი
იტერატორის მნიშვნელობას, ხოლო თუ ასეთი არ
მოიძებნა, აბრუნებს სიმრავლის დასასრულის (end())
იტერატორის მნიშვნელობას.

მაგალითი 0 /წყვილების შექმნა


#include <iostream>
#include <utility>
#include <string>
using namespace std;

int main()
{
pair<int, string> p1(2,"tel" );
cout << get<0>(p1)<<" , "<<get<1>(p1)<<endl;
cout << p1.first << endl;
cout << p1.second << endl;
pair<char, float> p2;
p2 = make_pair('e', 3.7);

2
cout << p2.first << endl;
cout << p2.second << endl;
auto p3 = make_pair("pal", 8);
cout << get<0>(p3)<<" , "<<get<1>(p3)<<endl;
}

შედეგი:

2 , tel

tel

3.7

pal , 8

Press any key to continue .


..

მაგალითი 1/ასახვის შექმნა განაცხადის საშუალებით, ელემენტების შეტანა ასახვაში


insert, emplace da [] ოპერატორის საშუალებით, ერთი ასახვიდან მეორეში
ელემენტების გადაწერა

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main()
{
// m1 ასახვის შექმნა განაცხადით
map<int, string> m1{ { 5,"dato" },{ 7,"gia" },{ 0,"nino" } };

cout << " map m1: " << endl;


for (auto i = m1.begin(); i != m1.end(); i++)
cout << "(" << i->first << "," << i->second << ")";
cout << endl;

// m1 სიმრავლეში ელემენტების შეყვანა


m1.insert(make_pair(4, "ana"));
m1.insert(make_pair(-1, "keti"));
m1.insert(pair<int, string>(2, "vano"));
m1.insert(pair<int, string>(0, "vaso"));
m1.emplace(77, "rati");
m1.emplace(88, "soso");
m1[100] = "tato";

3
cout << endl;
cout << " map m1 after inserting: " << endl;
for (auto i = m1.begin(); i != m1.end(); i++)
cout << "(" << i->first << "," << i->second << ")";
cout << endl;

// ელემენტებიდან გასაღებით 0 შევა მხოლოდ პირველად შეტანილი


cout << endl;

// m2 ასახვაში m1 ასახვის გადმოწერა


map<int,string> m2(m1.begin(), m1.end());
cout << " map m2 after inserting m1: " << endl;
for (auto i = m2.begin(); i != m2.end(); i++)
cout << "(" << (*i).first << "," << (*i).second << ")";
cout << endl;
}

შედეგი:

map m1:

(0,nino)(5,dato)(7,gia)

map m1 after inserting:

(-1,keti)(0,nino)(2,vano)(4,ana)(5,dato)(7,gia)(77,rati)(88,soso)(100,tato)

map m2 after inserting m1:

(-1,keti)(0,nino)(2,vano)(4,ana)(5,dato)(7,gia)(77,rati)(88,soso)(100,tato)

Press any key to continue . . .

მაგალითი2 / ასახვაში ელემენტის ძებნა,ასახვიდან ელემენტის წაშლა/


#include <iostream>
#include <map>
#include <string>
#include <functional>
using namespace std;

int main()
{
// m1 ასახვის დალაგება გასაღების კლებადობის მიხედვით
map<string, int, greater<string>> m1{ { "dato", 95 },{ "gia",87 },{ "nino", 50 }};

cout << " map m1: " << endl;


for (auto i = m1.begin(); i != m1.end(); i++) {
cout << "(" << i->first << "," << i->second << ")";
}
cout << endl;

4
// ძებნა ხდება გასაღების მიხედვით,იპოვის "dato"-ს შესაბამის წყვილს და აბრუნებს მის
იტერატორს,
//თუ არ არის ამ გასაღების შესაბამისი წყვილი, გამოიტანს შეცდომას.
auto it = m1.find("dato");
cout << endl;
cout << "dato's score is: " << (*it).second << endl;
// m1-ში, "dato" გასაღების მქონე წყვილს შეუცვლის მნიშვნელობას.
m1["dato"] = 100;
cout << endl;
cout << " map m1 after changing value of element with key dato: " << endl;
for (auto i = m1.begin(); i != m1.end(); i++) {
cout << "(" << i->first << "," << i->second << ")";
}
cout << endl;
cout << endl;
string sakheli = "ana";
// რადგან "ana" გასაღების მქონე წყვილი არ შედის ასახვაში, ამიტომ m1.find(sakheli)
აბრუნებს m1.end()-ს.
if (m1.find(sakheli) != m1.end())
cout << "the pair with key "<< sakheli<< " is found" << endl;
else
cout << "the pair with key "<< sakheli<< " is not found" << endl;
cout << endl;

// ელემენტების წაშლა m1 ასახვიდან


// იტერატორით
//შლის წყვილს გასაღებით "dato" და აბრუნებს მომდევნო წყვილის იტერატორს.
//თუ წყვილი გასაღებით "dato" არ შედის ასახვაში, გამოაქვს კომპილერის შეცდომა.
auto i = m1.erase(m1.find("dato"));

// მნიშვნელობით
// შემდეგი ფრაგმენტი გამოიტანს 1-ს, თუ წყვილი გასაღებით "dato" წაიშალა ასახვიდან
და 0-ს, თუ წყვილი გასაღებით "dato" არ არის ასახვაში.
int erased_pair = m1.erase("nino");
cout << "is the pair erased ? " << erased_pair << endl;
cout << endl;
cout << "map m1 after erasing the element: " << endl;
for (auto it = m1.begin(); it != m1.end(); it++)
cout << "(" << it->first << "," << it->second << ")";
cout << endl;

5
map m1:

(nino,50)(gia,87)(dato,95)

dato's score is: 95

map m1 after changing value of


element with key dato:

(nino,50)(gia,87)(dato,100)

the pair with key ana is not


found

is the pair erased ? 1

map m1 after erasing the


element:

(gia,87) Multimap -ის ძირითადი თვისებები და ფუნქციები

Press any key to continue . . .


o ელემენტები დალაგებულია (გულისხმობის პრინციპით,ზრდადობით)
o map-გან განსხვავებით, შეიძლება შეიცავდეს ერთნაირ ელემენტებს.
o Multimap-ში არ არის გადატვირთული [] და at ოპერატორები.

multimap-ის ძირითადი ფუნქციები ემთხვევა map-ის ფუნქციებს, მაგრამ არის


ფუნქციები, რომლებიც multimap - ში უფრო ეფექტურად არის გამოყენებული.
ზოგიერთი ასეთი ფუნქციაა:

Lower_bound(x) აბრუნებს პირველ x ელემენტს დალაგებულ


მულტიასახვაში.
Upper_bound( x) აბრუნებს ბოლო x ელემენტის შემდეგ ელემენტს
დალაგებულ მულტიასახვაში.
Equal_range (x) აბრუნებს დიაპაზონს Lower_bound-დან Upper_bound-დე.
erase (x) შლის ყველა x გასაღების მქონე ელემენტს ასახვიდან და
აბრუნებს წაშლილი ელემენტების რაოდენობას.

6
erase (a.find(x)) შლის x გასაღების მქონე მხოლოდ ერთ ელემენტს a
სიმრავლიდან.
count(x) აბრუნებს xგასაღების მქონე ელემენტების რაოდენობას
სიმრავლეში.

მაგალითი3 /მულტიასახვის შექმნა განაცხადით, ასახვაში ელემენტების


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

#include <iostream>
#include <map>
#include<functional>

using namespace std;

int main()
{
// mm1 ასახვის შექმნა განაცხადით
multimap<int, char, greater<>> mm1{ { 5,'a' },{ 7,'s' },{ 0,'K' },{ 7,'z' },{
10,'s' } };
//multimap<int, char, greater<>> mm3;
cout << " multimap mm1: " << endl;
for (auto i = mm1.begin(); i != mm1.end(); i++)
cout << "(" << i->first << "," << i->second << ")";

cout << endl;

// mm1 ასახვაში ელემენტების შეყვანა

mm1.insert(pair<int, char>(4, '4'));


mm1.emplace(7, 'm');

cout << " map mm1 after inserting: " << endl;
for (auto i = mm1.begin(); i != mm1.end(); i++)
cout << "(" << i->first << "," << i->second << ")";
cout << endl;

// მულტიასახვა შეიცავს ერთნაირ ელემენტებს


// mm1-მულტიასახვიდან mm2 ასახვაში ელემენტების გადაწერა
//ერთნაირი გასაღების მქონე ელემენტებიდან აირჩევს პირველს, დაალაგებს გასაღების
ზრდადობის მიხედვით
map<int, char> mm2(mm1.begin(), mm1.end());

// აბრუნებს mm2-ს ყველა ელემენტს


cout << "\nThe multimap mm2 \n"
"after assign from mm1 is : \n";
for (auto it = mm2.begin(); it != mm2.end(); ++it) {
cout << "(" << it->first << "," << it->second << ")";
}
cout << endl;

7
//mm2 ასახვიდან იმ ელემენტების წაშლა, რომლის გასაღებიც 5-ზე ნაკლებია.
cout << "\n remove all elements up to element with key 5 in mm2: \n";
mm2.erase(mm2.begin(), mm2.find(5));
for (auto it = mm2.begin(); it != mm2.end(); ++it) {
cout << "(" << it->first << "," << it->second << ")";
}

// mm1 ასახვიდან ყველა 7 გასაღების ტოლი ელემენტის ამოღება

int num = mm1.erase(7);//აბრუნებს წაშლილი ელემენტების რაოდენობას


cout << "\n remove all elements with key 7: \n";
cout << num << " elements removed with key 7 \n ";
cout << "\n mm1 after removing elements with key 7 : \n";
for (auto it = mm1.begin(); it != mm1.end(); ++it) {
cout << "(" << it->first << "," << it->second << ")";
}
cout << endl;
}

8
multimap mm1:

(10,s)(7,s)(7,z)(5,a)(0,K)

map mm1 after inserting:

(10,s)(7,s)(7,z)(7,m)(5,a)(4,4)(0,K)

The multimap mm2

after assign from mm1 is :

(0,K)(4,4)(5,a)(7,s)(10,s)

remove all elements up to


element with key 5 in mm2:

(5,a)(7,s)(10,s)

remove all elements with key 7:

3 elements removed with key 7

mm1 after removing elements


with key 7 :

(10,s)(5,a)(4,4)(0,K)

Press any key to continue . . .

9
მაგალითი 4 /ასახვის ფუნქციების გამოყენებით შექმენით სასრულ სიმრავლეზე
განსაზღვრული ფუნქცია და გამოიტანეთ წყვილები

#include<iostream>
#include<set>
#include<map>
using namespace std;
int f(int x) {
return 4 * x - 7;
}

int main() {
set<int> s1{ -1,-2,-3,1,2,3,4,9,6,7,8,5 }, s2, s3;
map<int, int> m,m1;
for (auto i = s1.begin(); i != s1.end(); i++) {
y= f(*i);
m[*i] = y; m1.emplace(*i, y ); //ერთი და იგივე ასახვას ვქმნით ორი ხერხით
s2.insert(y);
}
cout << "m1 aris:" << endl;
for (auto it = m1.begin(); it != m1.end(); it++) {

cout << "("<<it->first << "," << it->second<<")";


}
cout <<"\n m aris:" << endl;
for (auto it = m.begin(); it != m.end(); it++) {

cout << it->first << "\t" << it->second << endl;


}
}

10
m1 aris:

(-3,-19)(-2,-15)(-1,-11)(1,-3)(2,1)(3,5)(4,9)(5,13)(6,17)(7,21)(8,25)(9,29)

m aris:

-3 -19

-2 -15

-1 -11

1 -3

2 1

3 5

4 9

5 13

6 17

7 21

8 25

9 29

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

1. “data.txt” ფაილში წერია მონაცემები შემდეგი ( წყვილების) სახით:


3 7 4 9 5 12 9 7 11 10 17 2 დაწერეთ პროგრამა რომელიც
წაიკითხავს ამ მონაცემებს ფაილიდან და ჩაწერს multimap-ში emplace მეთოდის
გამოყენებით. შემდეგ კი გაარკვევს და დაბეჭდავს შესაბამის გზავნილს არის თუ
არა ეს ასახვა ფუნქცია.
2. შეცვალეთ data.txt ფაილში ჩაწერილი მონაცემები შემდეგით

11 7 4 9 5 12 9 7 11 10 17 2

და შეასრულეთ წინა ამოცანაში დასმული დავალება.

3. “Monacemebi.txt” ფაილში მოცემულია ფუნქცია წყვილების სახით:


წაიკითხეთ და ჩაწერეთ ეს მონაცემები map-ში [] ოპერატორის საშუალებით,
შემდეგ დაბეჭდეთ განსაზღვრის არე, ანასახების სიმრავლე და map-ის
ელემენტები.

11
4. შექმენით map ასახვა, კლავიატურიდან შეყვანილი 10 წყვილისთვის. დაბეჭდეთ
მისი განსაზღვრის არე, ანასახების სიმრავლე. გაარკვიეთ, არის თუ არა ეს ასახვა
ფუნქცია და დაბეჭდეთ შესაბამისი გზავნილი.

12

You might also like