BAB
12.
STL
(Standard Template Library)
12.1 Pengantar
STL (Standard Template Library)
merupakan sebuah koleksi yang terdiri-dari sejumlah kode yang dapat
didaur-ulang, yang menangani pelbagai struktur data dan operasi yang umum
digunakan oleh para programer. Konsep ini pertama kali dikembangkan oleh
Alxender Stepanov dan Meng Lee dari Hawlett-Packard. Koleksi ini kemudian
dikembangkan oleh banyak peneliti dan pakar dalam pemrograman C++. STL sekarang
merupakan bagian dari pustaka standar C++.
Dengan menggunakan komponen-komponen STL, programer dapat menghemat waktu
dan tenaga. Hal itu juga untuk memastikan derajat efisiensi dan akurasi dari
program, karena STL ditulis dan diuji oleh para pakar. STL merupakan sekumpulan
besar program, yang memiliki tiga komponen utama:
a.
Kontainer-kontainer
b.
Iterator-iterator
c.
Algoritma-algoritma
Kontainer adalah objek yang menyimpan objek-objek lain. Objek-objek yang
disimpan itu dapat berupa data bertipe fundamental atau data dengan tipe yang
ditentukan user. Penyimpanan, pembacaan, dan pelbagai operasi lain untuk
memanipulasi data didasarkan pada kelas-kelas template, jadi kontainer
mengijikan penyimpanan dan pemanipulasian sembarang tipe data.
Iterator berperan seperti pointer. Karena iterator didasarkan pada
kelas-kelas template, iterator dapat dipakai pada pelbagai tipe data. Fungsi
utama dari iterator adalah menyediakan akses terhadap elemen-elemen dari
kontainer. Jadi, iterator dapat dipakai untuk menjelajah kontainer dan
melakukan operasi-operasi pada elemen kontainer. Ada beberapa jenis iterator,
yang dikategorikan berdasarkan kapabilitasnya. Detilnya akan dijelaskan lebih
lanjut.
Algoritma adalah potongan-potongan kode yang bisa dipakai untuk
memanipulasi data di dalam kontainer dengan bantuan iterator. Algoritma tidak
hanya untuk kontainer STL, tetapi dapat pula dipakai pada objek-objek lain
seperti array atau string. Pada bab ini, semua topik yang telah disebutkan
tersebut akan diintroduksi, sedangkan detil pada kontainer runtun, kontainer
asosiatif, dan algoritma akan dibahas terpisah.
12.2 Kontainer
Kontainer dikategorikan ke dalam tiga grup utama: (i) kontainer runtun,
(ii) kontainer asosiatif, (iii) kontainer adapter seperti diilustrasikan pada
diagram berikut. Ketiganya kemudian dispesialisasi menjadi kontainer-kontainer
dengan fungsi-fungsi spesial, sehingga seorang programer dapat memilih mana
yang terbaik untuk dipakai dalam menyelesaikan aplikasi. Gambar berikut
menunjukkan relasi antara sejumlah kelas kontainer.
GAMBAR 12.1 Kontainer runtun, kontainer asosiatif,
dan kontainer adapter
Kontainer runtun dan kontainer asosiatif secara kolektif disebut dengan
kontainer kelas pertama karena keduanya dapat menyimpan dan memiliki
kapabilitas untuk memanipulasi data dengan bantuan iterator. Kedua kontainer
itu juga memiliki sejumlah fungsi pustaka. Kontainer adapter tidak mendukung
keberadaan iterator dan tidak dapat memanipulasi data. Kelas adapter hanya
memiliki sedikit fungsi pustaka, yang utamanya untuk menempatkan atau menghapus
data dari depan atau belakang runtun.
Kontainer runtun pada dasarnya adalah runtun data linier. Elemen data
individual dihubungkan dengan elemen-elemen lain berdasarkan posisinya di dalam
runtun. Kontainer ini mendukung penyisipan dan penghapusan data di dalam runtun
dan dapat mengalokasikan memori tambahan jika jumlah elemen bertambah melebihi
kapasitas (memori) yang semula dialokasikan. Oleh karena itu, kontainer ini
bersifat dinamis, tidak seperti array yang memiliki panjang tetap yang tidak
bisa diubah setelah dideklarasikan. Kontainer runtun ada tiga jenis: (i)
vector, (ii) deque (juga disebut dengan antrian ujung ganda, double ended queue), dan (iii) list.
Tiap kontainer ini mempunyai spesialitas berbeda.
Sebagai contoh, vektor memiliki akses acak cepat terhadap elemen dan
penghapusan cepat terhadap elemen di ujung belakang vektor, tetapi kontainer
ini lambat dalam penyisipan dan penghapusan di tengah vektor.
List cepat dalam penyisipan dan penghapusan di tengah dan di ujung depan
runtun tetapi tidak mendukung akses acak. List hanya mendukung iterator dwi-arah
(bidirectional), oleh karena itu, ia
lambat dalam mengakses elemen pada posisi acak. Sama halnya, deque mempunyai
kapabilitas akses acak begitu pula dengan penyisipan dan penghapusan di kedua
ujung, tetapi kontainer ini lambat dalam penyisipan atau penghapusan elemen di
tengah list. Deque juga mendukung iterator acak. Elemen data individual dapat
diakses oleh iterator dan bisa dimanipulasi. Sejumlah fitur kunci dari semua
kontainer ini diberikan pada Tabel 12.1.
TABEL 12.1 Sejumlah fitur dari semua kontainer
Kontainer
|
File header
|
Penjelasan
|
vector
|
<vector>
|
Kontainer ini menyediakan akses langsung terhadap
sembarang elemen. Penambahan dan penghapusan cepat di ujung belakang vektor.
Untuk fungsi-fungsi dan operator-operator yang didukung oleh kelas vector, lihat Bab 22.
|
list
|
<list>
|
Penyisipan dan penghapusan cepat pada sembarang lokasi di
dalam list. Untuk fungsi-fungsi dan operasi-operasi yang didukung oleh kelas
list, lihat Bab 22.
|
deque
|
<deque>
|
Memiliki akses langsung terhadap sembarang elemen dari
kontainer deque. Penambahan dan penghapusan cepat di kedua ujung antrian.
Untuk fungsi-fungsi dan operasi-operasi yang didukung oleh kelas deque, lihat
Bab 22.
|
set
|
<set>
|
Hanya nilai-nilai unik yang diijinkan. Salinan-salinan
duplikat diabaikan jika disisipkan. Nilai-nilai diurutkan dengan urutan yang
ditetapkan seperti urutan menaik atau urutan menurun, dan lainnya (Lihat Bab
23).
|
multiset
|
<set>
|
Sejumlah salinan (duplikasi) dari sebuah nilai diijinkan.
Elemen-elemen diurutkan dengan tatanan yang ditetapkan seperti pada set.
|
map
|
<map>
|
Kontainer ini menyimpan pasangan nilai untuk setiap
elemen, nilai pertama adalah kunci dan nilai kedua adalah nilai terkait.
Elemen-elemen diurutkan berdasarkan kunci dan hanya kunci-kunci unik yang
diijinkan. Untuk lebih lengkapnya, lihat Bab 23.
|
multimap
|
<map>
|
Kontainer ini menyimpan pasangan nilai untuk setiap
elemen, nilai pertama adalah kunci dan nilai kedua adalah nilai terkait.
Elemen-elemen diurutkan berdasarkan kunci dan duplikasi kunci diijinkan.
Untuk lebih lengkapnya, lihat Bab 23.
|
stack
|
<stack>
|
Tumpukan objek yang memiliki tatanan first in last out
(FILO) atau dengan kata lain objek yang belakangan dimasukkan atau menjadi
objek pertama yang akan dihapus. Untuk lebih detil, lihat Subbab 12.6 pada
bab ini.
|
queue
|
<queue>
|
Sebuah antrian objek. Tatanannya adalah first in fist out
(FIFO) dengan kata lain objek yang pertama dimasukkan atau menjadi objek
pertama yang akan dihapus. Untuk lebih detil, lihat Subbab 12.6.2 pada bab
ini.
|
priority queue
|
<queue>
|
Sebuah antrian objek. Elemen dengan prioritas tertinggi
berada di atas antrian dan akan menjadi elemen yang pertama dihapus. Untuk
lebih detil, lihat Subbab 12.6 pada bab ini.
|
12.3 Iterator
Iterator berperan seperti pointer, yang dipakai untuk mengakses elemen-elemen
kontainer. Iterator juga dipakai untuk menjelajah dari satu elemen ke elemen
lain dengan menggunakan operattor inkremen dan dekremen. Ada sejumlah tipe
iterator, seperti ditampilkan berikut ini.
Iterator
|
Penjelasan
|
input_iterator
|
Iterator ini
dapat dipakai untuk membaca nilai-nilai, yang juga dapat diinkremen dan hanya
bergerak maju. Operator-operator lain yang didukung oleh input_iterator
diberikan pada Tabel 12.2.
|
output_iterator
|
Iterator ini
dapat dipakai untuk menulis dan dapat diinkremen dan direferensi.
|
forward_iterator
|
Iterator ini dapat dipakai untuk membaca atau menulis,
yang hanya bisa bergerak maju.
|
bidirectional_iterator
|
Iterator ini
dapat dipakai untuk membaca atau menulis, yang dapat bergerak maju atau
mundur (dapat diinkremen maupun didekremen).
|
random_iterator
|
Iterator ini dipakai untuk mengakses secara acak terhadap
suatu elemen. Iterator ini dapat pula dipakai untuk pembacaan dan penulisan.
Iterator acak memiliki semua karakteristik dari iterator-iterator lain.
|
DEKLARASI ITERATOR
Deklarasi iterator untuk sebuah vector<int>
diilustrasikan sebagai berikut:
GAMBAR 12.2 Deklarasi dan penugasan suatu iterator
pada kelas vector
Deklarasi dan penugasan dapat digabungkan sebagai berikut:
vector<int> :: iterator
Iter = V1.begin();
Nilai dari elemen yang ditunjuk oleh iterator didapatkan dengan
menggunakan operator dereferensi (*). Sebagai contoh, nilai dari elemen pertama
pada vektor V1 dari deklarasi di atas diberikan oleh *Iter dan nilai dari elemen kedua adalah *(++Iter).
OPERATOR-OPERATOR PADA ITERATOR-ITERATOR
Ada lima tipe iterator yang telah didiskusikan sebelumnya. Setiap tipe
iterator mendukung sejumlah operator seperti dicantumkan pada Tabel 12.2.
TABEL 12.2 Operator-operator yang didukung oleh
pelbagai iterator
Input iterator
|
Output iterator
|
Forward iterator
|
Bidirectional
iterator
|
Random iterator
|
Penjelasan
|
++itr
|
++itr
|
++itr
|
++itr
|
++itr
|
pra-inkremen
|
itr++
|
itr++
|
itr++
|
itr++
|
itr++
|
pasca-inkremen
|
*itr
hanya untuk
membaca
|
|
*itr
|
*itr
|
*itr
|
nilai = *itr. Lihat program 12.1.
|
|
*itr
hanya untuk
menulis
|
*itr
|
*itr
|
*itr
|
*itr = nilai.
Lihat program 12.2.
|
itr1 == itr2
|
|
itr1 == itr2
|
itr1 == itr2
|
itr1 == itr2
|
perbandingan ekualitas
|
itr1 != itr2
|
|
itr1 != itr2
|
itr1 != itr2
|
itr1 != itr2
|
perbandingan inekualitas
|
|
|
|
|
itr1 = itr2
|
penugasan
|
|
|
|
--itr
|
--itr
|
pra-dekremen
|
|
|
|
itr--
|
itr--
|
pasca-dekremen
|
|
|
|
|
itr + k
|
bertambah sebesar int k
|
|
|
|
|
itr – k
|
berkurang sebesar int k
|
|
|
|
|
itr += k
|
bertambah sebesar int k dan penugasan
|
|
|
|
|
itr –= k
|
berkurang sebesar int k dan penugasan
|
|
|
|
|
[k]
|
operator subskript
|
|
|
|
|
itr1 < itr2
|
perbandingan kurang dari atau lebih kecil dari
|
|
|
|
|
itr1>itr2
|
perbandingan lebih dari atau lebih besar dari
|
|
|
|
|
itr1<=itr2
|
perbandingan lebih kecil dari atau sama dengan
|
|
|
|
|
itr1>=itr2
|
perbandingan lebih besar dari atau sama dengan
|
12.4 Kontainer
Runtun
Sejumlah fitur dari kontainer telah didiskusikan pada Tabel 12.1.
Kontainer runtun terdiri-dari tiga kontainer yaitu vector, list, dan deque. Di
sini, akan diberikan beberapa contoh ilustratif dari ketiga kontainer tersebut.
Untuk lebih detil, silahkan lihat Bab 22.
VEKTOR
Vektor adalah array dinamis. Jumlah elemen bisa berubah selama eksekusi
program. Di sini, beberapa fitur dari vektor akan diilustrasikan. Program
berikut memberikan sebuah ilustrasi dari vektor, iterator, dan fungsi push_back(), begin(), end(), dan
lainnya. Untuk fungsi-fungsi dan operator-operator lain yang didukung oleh
kelas vector, silahkan lihat Bab 22.
Program 12.1 Mengilustrasikan
aplikasi dari vektor dan input iterator dari istream
|
|
|
#include<iostream>
#include<vector>
#include <iterator>
using namespace std;
vector<int> V; //Deklarasi dari sebuah
vektor dengan elemen-elemen int
int main()
{
cout<<"Masukkan 5 integer:
"<<endl;
istream_iterator <int> readit(cin);
//input iterator
/*Berikut adalah fungsi push_back() yang
dipakai untuk menambahkan elemen-elemen
di belakang sebuah vektor V.*/
V.push_back (*readit++);
V.push_back (*(readit++));
V.push_back (*(readit++));
V.push_back (*(readit++));
V.push_back (*(readit));
cout<<"Elemen-elemen dari V
adalah: ";
vector<int>:: iterator iter = V.begin();
/*vector adalah nama kelas, iterator
adalah katakunci. iter adalah nama iterator.
Fungsi begin() menghasilkan iterator
yang menunjuk ke elemen pertama dari V.
Kelas vector mendukung keberadaan
iterator random (acak).*/
while(iter
!= V.end())
//end() menghasilkan iterator yang menunjuk ke tepat setelah elemen terakhir
dari vektor
cout<<*iter++ <<"
"; //menampilkan nilai-nilai elemen dari vektor
return
0;
}
|
KELUARAN
|
|
Masukkan 5
integer:
20 30 40 50 60
Elemen-elemen
dari V adalah: 20 30 40 50 60
|
Berikut adalah program lain yang menangani vektor dan menggunakan iterator
untuk menjelajah vektor tersebut.
Program 12.2 Mengilustrasikan aplikasi dari vektor dan input
iterator dari istream untuk menjelajah vektor
|
|
|
#include<iostream>
#include<vector>
#include <iterator>
using namespace std;
vector<int> V; //Deklarasi dari sebuah vektor dengan
elemen-elemen int
int main()
{
cout<<"Masukkan 5 integer:
"<<endl;
int
hitung =0;
while
(hitung <=4)
{
istream_iterator <int>
readit(cin); //input iterator
V.push_back (*readit);
++hitung;
}
//Vektor dikonstruksi dengan menempatkan
elemen-elemen di belakang vektor.
cout<<"\nElemen-elemen dari V
adalah: ";
vector<int>:: iterator iter =
V.begin(); // iterator didefinisikan
//iter adalah nama iterator, yang akan
dipakai untuk menjelajah vektor
while(iter
!= V.end())
{
cout<< *iter <<"
";
iter++;
}
return
0;
}
|
KELUARAN
|
|
Masukkan 5
integer:
30 45 56 67 78
Elemen-elemen
dari V adalah: 30 45 56 67 78
|
DEQUE
Program berikut mengilustrasikan operasi-operasi pada sebuah deque,
seperti deklarasi deque, konstruksi deque, dan input iterator dan output
iterator dari iostream. Deque juga mendukung random iterator sehingga semua
elemen dapat diakses secara langsung. Untuk lebih detil tentang deque, silahkan
lihat Bab 22.
Program 12.3 Mengilustrasikan aplikasi dari input iterator dan
output iterator pada deque
|
|
|
#include<iostream>
#include<deque>
#include <iterator>
using namespace std;
deque<int> Dek; //deklarasi deque dengan
elemene-elemen int
int main()
{
cout<<"Masukkan 4 buah integer:
"<<endl;
int
hitung =0;
while
(hitung < 4)
{
istream_iterator <int>
readit(cin);
Dek.push_back (*readit);
++hitung;
}
int
k=0;
cout<<"\nElemen-elemen dari Dek
adalah: ";
while
(k <4)
{
ostream_iterator <int>
writeit(cout);
* writeit= * (Dek.begin()+k );
cout<<" ";
k++;
}
return
0;
}
|
KELUARAN
|
|
Masukkan 4 buah
integer:
12 34 56 78
Elemen-elemen
dari Dek adalah: 12 34 56 78
|
LIST
Program berikut mengilustrasikan kontainer list. List ini seperti senarai
berantai ganda (doubly linked list). Program ini mengilustrasikan deklarasi
list, konstruksinya, dan bagaimana menampilkan elemen-elemen list.
Program 12.4 Mengilustrasikan konstruksi dari list dan bagaimana
mengisi dan menampilkan list
|
|
|
#include<iostream>
#include<list>
using namespace std;
list<char> Lc ; //deklarasi dari sebuah list dengan nama Lc dan bertipe char
list<int> Li (7,60); //deklarasi dari sebuah list dengan Li
//list ini memiliki 7
elemen int dengan tiap nilai 60
int main()
{
for
(int i=0; i<6;i++)
Lc.push_back(65+i); //Menambahkan
elemen-elemen di belakang list Lc
cout<<"Elemen pertama dari Lc
adalah "<<Lc.front()<<" dan elemen akhirnya adalah
"
<<Lc.back()<<endl;
//menampilkan elemen pertama dan elemen akhir
list<double>Ld(3,2.5); //List Ld mempunyai
tiga elemen masing-masing dengan nilai 2.5
for
(int j =0; j< 3; j++)
{
Ld.push_back( 5.5); //Menambahkan 3
elemen, dengan nilai 10.5, di belakang list
Ld.push_front( 10.5);
} //Menambahkan 3 elemen, dengan nilai
10.5, di depan list
cout<<"Lc = ";
list<double>::iterator itrd; //iterator
untuk list double
list<int>:: iterator itri; //deklarasi
iterator untuk list int
list <char>:: iterator itrc; //iterator
untuk list char
for(itrc=
Lc.begin(); itrc!=Lc.end(); itrc++)
cout << *itrc <<"
"; //menampilkan elemen-elemen dari list Lc.
cout<<"\nLi = ";
for(itri=
Li.begin(); itri!=Li.end(); itri++)
cout<<*itri<<" ";
// menampilkan elemen-elemen dari list Li.
cout<<"\n Ld = ";
for(itrd=
Ld.begin(); itrd!=Ld.end(); itrd++)
cout<<*itrd<<" ";
//menampilkan elemen-elemen dari list Ld.
cout<<"\nElemen pertama dari Ld
= " <<*(Ld.begin())<<endl;
cout<<"\nElemen ketiga dari Ld
dari awal = "<<*(++(++ Ld.begin())) ;
//kelas list tidak mendukung akses acak
cout<<"\nElemen ketiga dari Ld
dari akhir = "<< * (--(-- Ld.end()))<<endl;
return
0;
}
|
KELUARAN
|
|
Elemen pertama
dari Lc adalah A dan elemen akhirnya adalah F
Lc = A B C D E
F
Li = 60 60 60
60 60 60 60
Ld = 10.5 10.5 10.5 2.5 2.5 2.5 5.5 5.5 5.5
Elemen pertama
dari Ld = 10.5
Elemen ketiga
dari Ld dari awal = 10.5
Elemen ketiga
dari Ld dari akhir = 5.5
|
12.5 Kontainer
Asosiatif
Kontainer asosiatif mendukung pembacaan cepat atas elemen-elemen melalui
kunci-kunci. Kontainer asosiatif ini terdiri-diri (i) set, (ii) multiset, (iii)
map, dan (iv) multimap. Ukuran kontainer dapat berubah selama eksekusi program.
Elemen-elemen dari set asosiatif bertipe value_type.
Setiap elemen memiliki kunci yang bertipe key-type.
Pada kasus set dan multiset, nilai elemen itu sendiri adalah kunci. Pada kasus
map dan multimap, kunci berbeda dari nilai elemen. Jadi, pada set dan multiset,
sebuah elemen terdiri-dari satu nilai, sedangkan pada map dan multimap, sebuah
elemen terdiri-dari sepasang kunci dan nilai.
Set hanya mengijinkan kunci-kunci unik, sedangkan multiset mengijinkan
adanya kunci-kunci duplikat. Sama halnya, map hanya mengijinkan kunci-kunci
unik, sedangkan multimap mengijinkan adanya kunci-kunci duplikat. Program
berikut mengilustrasikan konstruksi dan pembacaan/penampilan dari sebuah map.
Program 12.5 Mengilustrasikan konstruksi dari map dan cara
menampilkan elemen-elemennya
|
|
|
#include<iostream>
using namespace std;
#include<map>
#include<string>
typedef map
<string, int> Mint;
/*typedef
digunakan untuk menghindari penulisan map<string, int> berulangkali.
Pada deklarasi,
kunci adalah sebuah string dan nilai int.*/
int main()
{
string Nama;
int
Skor;
Mint Nilai; //Nilai adalah nama map
for
(int i = 0; i<4; i++)
{
cout<<"Masukkan Nama:
";
cin>>Nama;
cout<<"Masukkan Skor:
";
cin>>Skor;
Nilai[Nama] = Skor;
} //membuat pasangan-pasangan nilai
Mint :: iterator iter; // deklarasi
iterator
for(iter
= Nilai.begin(); iter != Nilai.end(); iter++)
cout<<(*iter).first<<"\t"<<(*iter).second<<"\n";
/*first adalah kunci dan second adalah
nilai. Operator dot dipakai
untuk memilih first dan second.*/
return
0;
}
|
KELUARAN
|
|
Masukkan Nama:
Kristof
Masukkan Skor:
78
Masukkan Nama:
John
Masukkan Skor:
89
Masukkan Nama:
Vivian
Masukkan Skor:
99
Masukkan Nama:
Marolop
Masukkan Skor:
98
John 89
Kristof 78
Marolop 98
Vivian 99
|
12.6 Kontainer
Adapter: Tumpukan
(stack), Antrian (queue), dan Antrian Prioritas (priority queue)
Tumpukan, antrian, dan antrian prioritas adalah kontainer-kontainer
adapter di dalam STL. Ketiganya tidak mendukung adanya iterator dan tidak
memiliki struktur implementasi data sendiri seperti vektor, list, dan lainnya.
Namun ketiga kontainer adapter ini dapat beradaptasi dengan struktur data dari
kontainer lain. Oleh karena itu, programer dapat memilih kontainer yang cocok
dengan permasalahan yang akan ditangani.
TUMPUKAN
Tumpukan memiliki kapabilitas penyisipan dan penghapusan data di awal
(atas) tumpukan, dengan tatanan LIFO (last
in first out). Hal ini diilustrasikan pada Gambar 12.3, yang menunjukkan
bahwa piring-piring ditumpuk satu di atas yang lain. Untuk mengambil sebuah
piring, hal itu dilakukan dengan mengambilnya dari atas tumpukan. Jadi, piring
yang terakhir kali ditempatkan akan diambil pertama kali. Ada banyak aplikasi tumpukan,
sebagai contoh, kompiler membuat tumpukan kode mesin dari kode sumber.
Fungsi-fungsi yang didukung oleh kelas stack
dicantumkan pada Tabel 12.3.
GAMBAR 12.3 Tatanan LIFO (last in first out)
TABEL 12.3 Fungsi-fungsi yang berkaitan dengan tumpukan
Fungsi
|
Penjelasan
|
empty()
|
Fungsi ini
menghasilkan true jika tumpukan kosong.
|
pop()
|
Fungsi ini
menghapus sebuah elemen dari atas tumpukan.
|
push()
|
Fungsi ini
menempatkan sebuah elemen di atas tumpukan.
|
size()
|
Fungsi ini
menghasilkan jumlah elemen pada tumpukan.
|
top()
|
Fungsi ini menghasilkan elemen teratas pada tumpukan.
|
Program berikut mengilustrasikan implementasi dari sebuah tumpukan. Fungsi
push() dipakai untuk mengisi
tumpukan.
Program 12.6 Mengilustrasikan aplikasi dari beberapa fungsi pada
tumpukan
|
|
|
#include<iostream>
#include<stack>
using namespace std;
void main()
{
stack<int> St1 ; //St1 dideklarasikan sebagai tumpukan integer
for
(int i =1; i< 7; i++) //
konstruksi tumpukan oleh fungsi push()
St1.push (10* i);
//Elemen-elemen yang diisikan adalah 10,
20, 30, 40, 50, 60
//Pada tumpukan, tatanannya adalah LIFO
cout <<"Elemen teratas pada St1
= "<<St1.top()<<endl;
cout<<"Ukuran dari tumpukan
adalah = "<<St1.size()<<endl;
cout<<"Elemen-elemen dari St1
adalah: ";
while(!St1.empty())
//statemen untuk menampilkan elemen-elemen tumpukan
{
cout<<St1.top()<<"
";
St1.pop() ;
} //menghapus elemen teratas
}
|
KELUARAN
|
|
Elemen teratas
pada St1 = 60
Ukuran dari
tumpukan adalah = 6
Elemen-elemen
dari St1 adalah: 60 50 40 30 20 10
|
Pada program di atas, tumpukan dikonstruksi dengan menempatkan
nilai-nilai. Pada statemen keluaran, elemen teratas ditempatkan lebih dahulu ke
aliran keluaran, kemudian, elemen teratas itu dihapus dengan fungsi pop(). Elemen berikutnya setelah elemen
teratas tersebut ditempatkan ke aliran keluaran, dan kemudian dihapus. Proses
berlanjut sampai elemen terakhir dihapus. Dari keluaran program dapat dilihat
bahwa elemen pertama pada aliran keluaran adalah elemen terakhir yang
ditempatkan pada tumpukan. Program berikut menyajikan contoh lain dari
tumpukan.
Program 12.7 Mengilustrasikan contoh lain dari tumpukan dengan
beberapa tipe elemen berbeda
|
|
|
#include<iostream>
#include<stack>
#include <string>
using namespace std;
void main()
{
stack<int> Ski ; //deklarasi
tumpukan integer
stack<char> Sch; //deklarasi
tumpukan char
stack<string> Skt ; //deklarasi tumpukan string
string Nama[4]={"Jakarta",
"Medan", "Surabaya", "Bandung"};
char
ch[4] = {'B', 'A', 'C', 'T'};
int
Array[5] = { 10, 40, 60,20,10 };
for
(int i = 0;i < 4; i++)
{
Ski.push (Array[i]); //menempatkan 4 elemen pada tumpukan Ski
Sch.push (ch[i]); //menempatkan 4 elemen pada
tumpukan Sch
Skt.push (Nama[i]); //menempatkan 4 elemen pada tumpukan Skt
}
cout<<"Elemen teratas pada Skt
= "<<Skt.top()<<endl;
cout<<"Elemen teratas pada Sch
= "<<Sch.top()<<endl;
cout<<"Elemen teratas pada Ski
= "<<Ski.top()<<endl;
cout<<"Ukuran dari tumpukan Skt
adalah = "<<Skt.size()<<endl;
cout<<"Elemen-elemen dari
ketiga tumpukan adalah sebagai berikut: "<<endl;
for
(int j = 0;j < 4; j++)
{
cout<<Skt.top()<<"\t"<<
Sch.top()<<"\t"<<Ski.top()<<"\n";
Skt.pop() ; //menghapus elemen teratas pada Skt
Sch.pop(); //menghapus elemen teratas pada Sch
Ski.pop(); //menghapus elemen teratas pada Ski
}
}
|
KELUARAN
|
|
Elemen teratas
pada Skt = Bandung
Elemen teratas
pada Sch = T
Elemen teratas
pada Ski = 20
Ukuran dari
tumpukan Skt adalah = 4
Elemen-elemen
dari ketiga tumpukan adalah sebagai berikut:
Bandung T
20
Surabaya C
60
Medan A 40
Jakarta B
10
|
Program 12.8 Mengilustrasikan tumpukan dengan memanfaatkan
kontainer vektor
|
|
|
#include<iostream>
#include<stack>
using namespace std;
#include <vector>
int main()
{
stack <int, vector <int>
> Tumpukan1, Tumpukan2, Tumpukan3;
//Deklarasi tumpukan int
//Kontainer yang digunakan adalah vektor
int
Array1[] = {12, 13, 14, 15, 16};
int
Array2[] = {40, 60, 20, 10, 50};
for
(int i = 0;i < 5; i++)
{
Tumpukan1.push (Array1[i]);
Tumpukan2 .push (Array2[i]);
}
Tumpukan3 = Tumpukan2; // Tumpukan2
ditugaskan kepada Tumpukan3
cout<<"Ukuran dari Tumpukan3
adalah = "<<Tumpukan3 .size()<<endl;
if
( Tumpukan2 == Tumpukan3 ) // relational == operator
cout<< "Tumpukan3 dan
Tumpukan2 sama.\n";
else
cout<<"Tumpukan3 dan
Tumpukan2 tidak sama.\n";
Tumpukan3.push(80); //menambahkan elemen
lain pada tumpukan
cout <<"Sekarang ukuran dari
Tumpukan3 = "<<Tumpukan3.size()<<endl;
for
(int j = 0;j < 6; j++) //untuk
menampilkan elemen-elemen tumpukan
{
cout<<Tumpukan3.top()<<" " ; //menampilkan
elemen teratas pada Tumpukan3
Tumpukan3.pop(); // menghapus elemen
teratas dari Tumpukan3
}
cout<<endl;
return
0;
}
|
KELUARAN
|
|
Ukuran dari
Tumpukan3 adalah = 5
Tumpukan3 dan
Tumpukan2 sama.
Sekarang ukuran
dari Tumpukan3 = 6
80 50 10 20 60
40
|
ANTRIAN
Pada antrian, elemen-elemen data disisipkan di belakang antrian dan
dihapus dari depan antrian. Urutan yang sama terjadi pada antrian di kehidupan
nyata, dengan tatanan FIFO (first in
first out). Hal ini diilustrasikan pada gambar berikut. Antrian dapat diisi
dengan memanfaatkan fungsi push().
GAMBAR 12.4 Ilustrasi dari antrian
Sejumlah fungsi yang berkaitan dengan antrian dicantumkan pada Tabel 12.4.
TABEL 12.4 Fungsi-fungsi yang berkaitan dengan antrian
Fungsi
|
Penjelasan
|
back()
|
Fungsi ini menghasilkan
sebuah referensi yang menunjuk ke elemen terakhir di dalam antrian.
|
empty()
|
Fungsi ini
menghasilkan true jika antrian
kosong.
|
front()
|
Fungsi ini
menghasilkan sebuah referensi yang menunjuk ke elemen pertama di dalam
antrian.
|
pop()
|
Fungsi ini
menghapus sebuah elemen dari depan antrian.
|
push()
|
Fungsi ini menambahkan sebuah elemen di akhir antrian.
|
size()
|
Fungsi ini menghasilkan jumlah elemen di dalam antrian.
|
Program berikut mengilustrasikan sejumlah operasi pada antrian.
Program 12.9 Mengilustrasikan aplikasi dari sejumlah fungsi pada
antrian
|
|
|
#include<iostream>
#include<queue>
using namespace std;
void main()
{
queue <int> Q ;
for
(int i =1; i<7; i++)
Q.push (10* i);
//Pada antrian, tidak ada fungsi top(),
tetapi yang dimiliki
//adalah fungsi front().
//Penampilan elemen-elemen dari depan
antrian diilustrasikan
//di bawah ini.
cout<<"Elemen di depan antrian
Q adalah = "<<Q.front()<<endl;
cout<<"Ukuran dari antrian Q
adalah = "<<Q.size()<<endl;
cout<<"Elemen-elemen dari Q
adalah: ";
while(!Q.empty())
//statemen keluaran untuk antrian
{
cout<<Q.front()<<"
";
Q.pop();
}
cout<<endl;
}
|
KELUARAN
|
|
Elemen di depan
antrian Q adalah = 10
Ukuran dari
antrian Q adalah = 6
Elemen-elemen
dari Q adalah: 10 20 30 40 50 60
|
Program berikut mengilustrasikan sejumlah operator yang didukung oleh
kelas queue.
Program 12.10 Mengilustrasikan aplikasi dari sejumlah operator pada
antrian
|
|
|
#include<iostream>
#include<queue>
using namespace std;
int main()
{
queue<int> q2,q3 ;
queue<double> q1;
for
(int i =0; i< 6; i++)
{
q1.push (1.5*i);
q2.push (i*i);
}
q3 = q2; //operator penugasan
if(
q2 == q3)
cout<<"Sekarang antrian q2
dan q3 sama."<<endl;
else
cout<<"Sekarang antrian q2
dan q3 tidak sama."<<endl;
cout<<"Elemen-elemen antrian q2
adalah: ";
while(!q2.empty())
{
cout<<q2.front()<<"
" ;
q2.pop();
}
cout<<"\n";
cout<<"Elemen-elemen antrian q3
adalah: ";
while(!q3.empty())
{
cout<<q3.front()<<"
" ;
q3.pop();
}
cout<<"\n";
if(
q2 == q3)
cout<<"Antrian q2 dan q3
sama."<<endl;
else
cout<<"Antrian q2 dan q3
tidak sama."<<endl;
cout<<"menempatkan elemen lain,
10, ke dalam q3 \n";
q3.push (10);
cout<<"Elemen-elemen antrian q3
adalah: ";
while(!q3.empty())
{
cout<<q3.front()<<"
" ;
q3.pop();
}
cout <<"\n";
cout<<"Elemen-elemen antrian q1
adalah: ";
while(!q1.empty())
{
cout<<q1.front()<<"
" ;
q1.pop();
}
cout <<"\n";
return
0;
}
|
KELUARAN
|
|
Sekarang
antrian q2 dan q3 sama.
Elemen-elemen
antrian q2 adalah: 0 1 4 9 16 25
Elemen-elemen
antrian q3 adalah: 0 1 4 9 16 25
Antrian q2 dan
q3 sama.
menempatkan
elemen lain, 10, ke dalam q3
Elemen-elemen
antrian q3 adalah: 10
Elemen-elemen
antrian q1 adalah: 0 1.5 3 4.5 6 7.5
|
Pada program tersebut, tiga antrian dideklarasikan, yaitu dua antrian int dan satu antrian double. Antrian q1 dan q2 dikonstruksi
dengan fungsi push() sedangkan
antrian q3 dibuat sebagai salinan dari antrian q2. Elemen-elemen ditambahkan di
belakang antrian dan dihapus dari depan antrian. Aplikasi dari fungsi empty() dan front() dan operator ++ diilustrasikan. Setelah penugasan q3 = q2;, kedua antrian menjadi sama.
Setelah elemen-elemen dihapus, kedua antrian itu tetap sama karena tidak ada
lagi elemen di dalam kedua antrian. Kemudian sebuah elemen (10) ditambahkan ke
dalam q3. Sekarang, elemen di dalam q3 adalah 10. Pada baris terakhir dari
keluaran program, elemen-elemen dari q1 ditampilkan. Setelah ditampilkan, tidak
ada lagi elemen di dalam q1 karena semua elemen dihapus saat penampilan.
ANTRIAN PRIORITAS
Antrian prioritas merupakan antrian dimana di dalamnya elemen-elemen
diurutkan menggunakan sebuah predikat. Secara default, elemen dengan nilai
tertinggi berada di depan antrian. Sejumlah fungsi yang berkaitan dengan
antrian prioritas dicantumkan pada Tabel 12.5. Di sini, fungsi top() dipakai untuk menunjuk elemen
yang ada di ujung depan antrian, menggantikan fungsi front() yang digunakan pada antrian biasa.
TABEL 12.5 Fungsi-fungsi yang berkaitan dengan antrian prioritas
Fungsi
|
Penjelasan
|
empty()
|
Fungsi ini
menghasilkan true jika antrian
prioritas kosong.
|
top()
|
Fungsi ini
menghasilkan elemen pertama di dalam antrian prioritas.
|
pop()
|
Fungsi ini
menghapus sebuah elemen dari depan antrian prioritas.
|
push()
|
Fungsi ini menambahkan sebuah elemen di akhir antrian prioritas.
|
size()
|
Fungsi ini menghasilkan jumlah elemen di dalam antrian prioritas.
|
Program berikut mengilustrasikan aplikasi dari sejumlah fungsi ini.
Program 12.11 Mengilustrasikan antrian prioritas
|
|
|
#include<iostream>
#include<queue>
using namespace std;
void main()
{
priority_queue <int> PQ ; //deklarasi antrian prioritas
int
Array[6] = {10, 80, 90, 20, 40, 70};
for
(int i =0; i<6; i++)
PQ.push (Array[i]);
//pada antrian prioritas, tidak ada
front(), tetapi yang ada top()
cout<<"Elemen di atas (depan)
antrian PQ = "<<PQ.top()<<endl;
cout<<"Ukuran dari antrian PQ
adalah = "<<PQ.size()<<endl;
cout<<"Elemen-elemen dari PQ
adalah: ";
while(!PQ.empty())
{
cout<<PQ.top()<<"
";
PQ.pop();
}
cout<<endl;
}
|
KELUARAN
|
|
Elemen di atas
(depan) antrian PQ = 90
Ukuran dari
antrian PQ adalah = 6
Elemen-elemen
dari PQ adalah: 90 80 70 40 20 10
|
12.7 Objek
Fungsi (Predikat)
Objek fungsi adalah sebuah objek kelas yang berperan sebagai sebuah fungsi
dan menghasilkan nilai bool, yang didasarkan pada argumen (yang bisa berupa
elemen kontainer) memenuhi fungsi atau tidak. Pada beberapa algoritma,
elemen-elemen dari sebuah kontainer dipilih berdasarkan apakah elemen memenuhi
sebuah predikat atau tidak. Algoritma diimplementasikan untuk menghasilkan
nilai balik. Jika nilai balik adalah true,
maka algoritma diimplementasikan. Sebaliknya jika nilai balik false, maka algoritma tidak diimplementasikan.
Sebelum mendemonstrasikan objek fungsi, berikut akan disajikan sebuah fungsi
biasa yang berperan sebagai predikat.
Program 12.12 Mengilustrasikan fungsi global sebagai predikat di
dalam algoritma
|
|
|
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
bool Ganjil(int n) //definisi dari fungsi untuk
nilai-nilai ganjil
{
return n%2 ? true : false;
}
bool Genap(int m ) //definisi dari fungsi untuk
nilai-nilai genap
{
return
!(m%2) ? true: false;
}
int main()
{
int
S[] = {5, 6, 8, 7, 4, 3, 8, 10, 11, 12};
int
n = count_if(S, S+10, Genap);
/*count_if() adalah sebuah algoritma.
Genap adalah alamat dari
(pointer yang menunjuk ke) fungsi
Genap(). Fungsi count_if diimplementasikan
jika elemen memenuhi fungsi Genap*/
cout<<"Jumlah elemen genap pada
S adalah = "<<n<<endl;
int
K = count_if(S, S+10, Ganjil);
/*Ganjil adalah alamat dari
(pointer yang menunjuk ke) fungsi
Ganjil(). Fungsi count_if diimplementasikan
jika elemen memenuhi fungsi Ganjil*/
cout<<"Jumlah elemen ganjil
pada S adalah = "<<K<<endl;
return
0;
}
|
KELUARAN
|
|
Jumlah elemen
genap pada S adalah = 6
Jumlah elemen
ganjil pada S adalah = 4
|
Pada kasus di atas, elemen-elemen diperiksa apakah dapat dibagi dengan 2
(divisibel, tanpa sisa) atau tidak dan sesuai dengan nilai balik bool, true atau false, elemen tersebut akan dihitung atau ditolak. Salah satu
fungsi (Ganjil) menguji apakah elemen merupakan nilai ganjil sedangkan fungsi
kedua (Genap) menguji apakah elemen merupakan nilai genap. Meskipun sebenarnya
hanya satu fungsi yang diperlukan, kedua fungsi dicantumkan untuk
mengilustrasikan kedua bentuk fungsi. Pemilihan genap atau ganjil didasarkan
pada nilai balik dari kedua fungsi tersebut.
Sama halnya, Anda dapat mendefinisikan sebuah fungsi untuk menentukan
apakah integer tertentu divisibel (dapat dibagi tanpa menghasilkan sisa) oleh
integer lain atau tidak. Pada kasus semacam itu, jika pembagi diubah, maka,
untuksetiap pembagi baru, program juga perlu diubah. Adalah lebih baik
mendefinisikan sebuah kelas dengan fungsi sebagai objek dari kelas itu. Hal ini
lebih mudah karena objek kelas dapat memuat data (pembagi, pada kasus itu).
Dengan skema semacam itu, fungsi tersebut dinamakan dengan objek fungsi, yang
diilustrasikan berikut ini.
Program 12.13 Mengilustrasikan definisi predikat sebagai kelas
template
|
|
|
#include<iostream>
#include<algorithm>
using namespace std;
template <class T>
class LBS { // LBS =
Lebih Besar atau Sama dengan
private
:
T x;
public
:
LBS (T A){x = A;} //konstruksi fungsi
bool
operator() (T y)
{return y >= x ? true
:false;}
}; // akhir
kelas
int main()
{
LBS <int> lbs(30); //lbs
dideklarasikan sebagai objek dari LBS untuk int
LBS <double> lbs2(25.0); //lbs2
adalah objek untuk double 25.0
int
S[] = {10, 20, 30, 36, 44, 60, 70};
double
SD[] = {3.5, 27.5, 22.6, 56.7, 80.0, 90.7, 65.5, 35.5};
//count_if() adalah sebuah algoritma
int
m = count_if(S, S+7, lbs); //di
sini lbs adalah predikat
cout<<"Jumlah elemen dengan S
>= 30 adalah = "<<m<<endl;
int
n = count_if(SD, SD+8, lbs2); //di
sini lbs2 adalah predikat
cout<<"Jumlah elemen dengan SD
>= 25.0 adalah = "<<n<<endl;
return
0;
}
|
KELUARAN
|
|
Jumlah elemen
dengan S >= 30 adalah = 5
Jumlah elemen
dengan SD >= 25.0 adalah = 6
|
Pada program tersebut, objek lbs
dan lbs2 berperilaku seperti fungsi.
Nilai-nilai inisialisasi untuk kedua objek itu, 30 dan 25.0, menjadi argumen
fungsi. Hal ini merupakan pilihan yang lebih baik daripada fungsi predikat pada
program sebelumnya.
Ada sejumlah predikat pustaka di dalam C++, seperti dicantumkan padan
Tabel 12.6 berikut. Seperti yang telah didemonstrasikan sebelumnya, user dapat
mengembangkan predikatnya sendiri.
12.8 Predikat-Predikat
Pustaka dalam C++
Ada sembilan predikat relasional dan logikal yang didefinisikan di dalam
file header <functional>.
Sejumlah predikat yang disediakan di dalam file header itu dicantumkan pada
Tabel 12.6.
TABEL 12.6 Predikat-predikat pustaka di dalam file header <functional>
Predikat
|
Unary/binary
|
Operasi ekivalen
|
plus
|
binary
|
x + y
|
minus
|
binary
|
x – y
|
multiplies
|
binary
|
x * y
|
divides
|
binary
|
x / y
|
modulus
|
binary
|
x % y
|
negate
|
unary
|
-x
|
equal_to
|
binary
|
x==y
|
not_equal_to
|
binary
|
x!=y
|
greater
|
binary
|
x>y
|
greater_equal
|
binary
|
x>=y
|
less
|
binary
|
x<y
|
less_equal
|
binary
|
x<=y
|
logical_and
|
binary
|
x&&y
|
logical_or
|
binary
|
x||y
|
logical_not
|
unary
|
!x
|
Ilustrasi kegunaan dari beberapa predikat diberikan oleh program 12.14
berikut ini.
Program 12.14 Mengilustrasikan aplikasi predikat greater dan less
dengan algoritma sort()
|
|
|
#include<iostream>
#include<algorithm>
#include<functional> //file header untuk predikat-predikat pustaka
using namespace std;
int main()
{
int
S[8] = {5, 6, 8, 7, 4, 3, 8, 9};
char
ch[] = {'A', 'Z', 'C', 'M', 'G', 'K', 'T'};
sort(S, S+8, less<int>()); //menata
dengan urutan menaik
sort(ch, ch+7, greater<int>()); //menata dengan urutan menurun
for
(int i =0; i<8;i++)
cout<<S[i]<<" ";
cout <<endl;
for
(int j =0; j< 7 ; j++)
cout << ch[j]<<"
";
cout<<endl;
return
0;
}
|
KELUARAN
|
|
3 4 5 6 7 8 8 9
Z T M K G C A
|
Pada baris pertama dari keluaran, elemen-elemen array diurutkan dengan
tatanan menaik. Pada baris kedua dari keluaran, karakter-karakter diurutkan
dengan tatanan menurun.
12.9 Fungsi Binder
Ketika setiap elemen runtun dibandingkan dengan suatu nilai untuk
kepentingan aksi selanjutnya, adalah lebih baik mengikat nilai itu dengan
predikat menggunakan fungsi binder. Dua fungsi biner didefinisikan berikut.
bind1st(x) //memanggil
atau mengikat fungsi dengan x sebagai argumen pertama.
bind2nd(y) //memanggil
atau mengikat fungsi dengan x sebagai argumen kedua.
Aplikasi dari bind2nd()
diilustrasikan pada program berikut.
Program 12.15 Mengilustrasikan aplikasi dari bind2nd()
|
|
|
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
template <class T>
struct LbhBesar:
binary_function< T, T, bool>
{
bool
operator ()(const T & x, const T& y) const
{
return
( x >y );
}
};
int main()
{
int
S[10] = {5, 6, 8, 7, 4, 3, 8, 9, 12, 14};
int
n = count_if( S, S +10, bind2nd(LbhBesar<int>(), 7));
cout<<"Jumlah elemen yang lebih
besar dari 7 adalah: "<<n<<endl;
return
0;
}
|
KELUARAN
|
|
Jumlah elemen
yang lebih besar dari 7 adalah: 5
|
Program berikut menggunakan objek fungsi pustaka greater dan less.
Program 12.16 Mengilustrasikan aplikasi dari predikat greater dan
less dengan fungsi bind2nd()
|
|
|
#include<iostream>
#include<algorithm>
using namespace std;
#include<functional>
int main()
{
int
S[] = {5, 6, 8, 7, 8, 3, 8, 10, 8, 12};
int
n = count_if(S, S+10, bind2nd(greater<int>(),7));
cout<<"Jumlah elemen yang lebih
besar dari 7 adalah: "<<n<<endl;
int
m = count_if(S, S+10, bind2nd(less<int>(),10));
cout<<"Jumlah elemen yang lebih
kecil dari 10 adalah: "<<m <<endl;
return
0;
}
|
KELUARAN
|
|
Jumlah elemen
yang lebih besar dari 7 adalah: 6
Jumlah elemen
yang lebih kecil dari 10 adalah: 8
|
LATIHAN
1.
Apa itu STL?
2.
Apa
komponen-komponen utama dari STL?
3.
Apa itu
iterator?
4.
Kontainer-kontainer
manakah yang dikatakan sebagai kontainer-kontainer kelas pertama dan mengapa?
5.
Bagaimana
kontainer asosiatif berbeda dari kontainer runtun?
6.
Bagaimana
iterator dideklarasikan? Berikan beberapa contoh deklarasi iterator untuk tiap
kasus berikut:
a.
vektor dengan
elemen-elemen int.
b.
deque dengan
elemen-elemen double.
c.
list dengan
elemen-elemen berupa nama-nama.
7.
Apakah tumpukan
mendukung iterator?
8.
Apa perbedaan
antara antrian dan antrian prioritas?
9.
Tuliskan sebuah
program untuk mengilustrasikan aplikasi dari tiap fungsi berikut:
a.
push()
b.
top()
c.
size()
10.
Tuliskan sebuah
program untuk mengilustrasikan aplikasi dari tiap fungsi berikut:
a.
size()
b.
push()
c.
pop()
11.
Bagaimana
tumpukan berbeda dari vektor?
12.
Apa itu
predikat?
13.
Definisikanlah
predikat fungsi untuk mengurutkan sebuah array dengan ururtan menaik.
14.
Apa itu fungsi
binder?
15.
Tulislah sebuah
program untuk memilih nilai-nilai genap dari sebuah runtun integer.
No comments:
Post a Comment