Stack
Stack
9.1. Pendahuluan
Stack merupakan list linear yang penghapusan (pop) dan penambahan (push)
elemen hanya dilakukan pada satu sisi yang disebut Top of Stack. Karena penambahan dan
penghapusan hanya pada satu sisi maka dikatakan stack mempunyai sifat LIFO (Last In
First Out) yaitu elemen yang paling akhir ditambahkan adalah elemen yang paling dulu
dihapus dari stack. Ilustrasi stack dapat dilihat pada gambar 9.1 di bawah ini.
Top of Stack
Bottom of Stack
Gambar 9.1 Struktur data Stack
75
Praktikum C++ Lanjut
Fungsi ini hanya memberi nilai awal pada variabel Tos. Deklarasi array yang
digunakan sebagai stack dan variabel Tos dilakukan pada program utama sehingga
keduanya merupakan global variabel yang dapat diakses oleh semua fungsi.
Contoh deklarasi:
int Tos;
char S[100]; //stack menyimpan maksimum 100 elemen
2. Stack kosong?:
int isEmpty()
{
if (Tos == 0)
return (1);
else
return (0);
}
Jika isi variabel Tos = 0, berarti stack kosong, selain itu stack tidak kosong. Fungsi ini
dapat dibuat fungsi yang berjenis boolean yang menghasilkan true atau false.
3. Push elemen ke stack:
void PUSH(char *S,char X)
{
if (Tos>=N)
cout<<endl<<"Error, Stack is Full!!!" << endl;
else
{
Tos = Tos+1; // increment Tos
S[Tos]=X;
}
}
Karena panjang array yang terbatas, maka stack yang diimplementasikan array menjadi
terbatas juga. Jika varibel Tos sudah mencapai akhir array, maka operasi Push tidak
dapat dilakukan lagi. Untuk mengatasi agar tidak terjadi stack overflow, beberapa buku
referensi melakukan perubahan panjang array sehingga menjadi lebih besar 2 kali
ukuran semula. Tetapi tidak semua bahasa pemrograman mempunyai fasilitas untuk
melakukan perubahan panjang array di tengah program.
4. Pop elemen dari stack:
char POP(char *S)
{ char Temp;
if (Tos == 0)
{ cout<<endl<<"Error, Stack is Empty "<< endl;
Temp = '#';
return (Temp);
}
else
{ Temp = S[Tos];
Tos = Tos-1; // decrement Tos
return(Temp);
}
}
Seperti telah dijelaskan di atas, elemen yang dihapus dari stack adalah elemen yang
paling atas atau yang berada pada Top of Stack. Setelah elemen dihapus, variabel Tos
di-decrement. Untuk menunjukkan bahwa stack kosong, maka digunakan simbol ’#’
sebagai output dari fungsi ini.
5. Melihat elemen stack yang paling atas
char TOP(char *S)
{
if (Tos == 0)
{ cout<<endl<<"Stack kosong"<< endl;
return ('#');
}
return (S[Tos]);
}
Fungsi ini hanya melihat elemen yang berada pada Top of Stack. Sama seperti fungsi
POP di atas, jika stack kosong maka akan dihasilkan karakter’#’.
Struktur data Stack dapat digunakan untuk memeriksa pasangan tanda kurung,
mengkonveri ekspresi infix menjadi suffix serta mengevaluasi ekspresi suffix
Untuk masalah ini, dapat digunakan array yang bertipe char sehingga tiap elemen stack
hanya berupa sebuah karakter. Untuk memudahkan dalam pemrograman, hanya ada 3
pasang tanda kurung yang digunakan dan program hanya memeriksa pasangan tanda
kurung saja. Fungsi untuk masalah ini dapat dilihat pada gambar 9.2 di bawah ini.
void pasangan()
{
char eksp[N]; // string untuk menyimpan ekspresi
char s, t;
int i,p;
if (isEmpty() == 1)
cout<<"Pasangan tanda kurung sesuai"<<endl;
else
cout<<"Tanda kurung tidak berpasangan"<<endl;
system(“pause”);
}
Gambar 8.2 Fungsi untuk memeriksa pasangan tanda kurung
kurung. Caranya dengan menuliskan operator setelah kedua operan, atau L R O yaitu Left
operand, Right operand, Operator. Sebagai contoh penulisan postfix dan padanan infix-nya
dapat dilihat pada tabel 9.1 di bawah ini.
Untuk mengubah ekspresi infix menjadi postfix, digunakan struktur data stack
sebagai tempat penyimpan sementara. Algoritma umum untuk mengubah Infix menjadi
Postfix:
1. Buat stack kosong
2. Baca simbol sampai akhir ekspresi.
3. Jika simbol berupa:
a. Operan: langsung tuliskan sebagai output
b. Kurung buka: push ke stack
c. Kurung tutup: pop stack sampai ketemu kurung buka (tanda kurung tidak ditulis
sebagai outpush)
d. Operator yang derajatnya lebih rendah dari TOP of Stack: pop stack sampai ketemu
operator yang derajatnya lebih rendah, lalu push ke stack:
e. Operator yang derajatnya lebih tinggi dari Top of Stack: push ke stack
f. Akhir simbol: pop stack sampai stack kosong.
Yang perlu diperhatikan dalam menterjemahkan algoritma di atas menjadi program adalah
pada langkah 3.d. Program komputer tidak dapat mengenal operator dan derajatnya.
Dengan demikian perlu dibuat 1 fungsi untuk membandingkan operator yang ada pada Top
of Stack dengan operator yang dibaca. Contoh fungsi dapat dilihat pada gambar 9.3 di
bawah ini.
{
case '+': { if (b == '+' || b =='-' || b == '*')
return(1);
else
return(0); // isi top of stack = '(' atau empty
break;}
case '-':{ if (b == '+' || b =='-' ||b == '*')
return(1);
else
return(0);
break;}
case '*':{ if (b == '*')
return(1);
else
return(0); //isi Tos = '(' , '+' , '-' , atau
empty
break}
}
void infix()
{
char postfix[N],eksp[N];
char x,y, Temp;
int i,j,p,t;
t = 0;
cout<<"Masukkan ekpresi Matematika = ";
cin>>eksp;
cout<<endl;
Inisialisasi(); // inisialisasi stack
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i]; // baca ekspresi per karakter
if (x == '(')
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*')
{ // jika x adalah operator
y = TOP(S);
if (y == '#') // jika stack kosong
PUSH(S,x);
else
{ j = cek(x,y); // bandingkan x dengan
while (j == 1) // operator pada Tos
{ //jika derajat < atau
sama
postfix[t]=POP(S); //pop stack
&
t++; //simpan ke array output
y = TOP(S);
j = cek(x,y);
}
PUSH(S,x);
}
}
else if(x == ')') // jika x = ‘)’
{
Temp = POP(S); // pop stack & simpan
while(Temp != '(') // ke array output
{ // sampai ketemu ‘)’
postfix[t]=Temp;
t++;
Temp = POP(S);
}
}
else
{ postfix[t]= x ; // eksp[i] == operan
t++; // simpan ke output
}
}
t--;
cout<<"Selesai ekspresi"<< endl;
p = isEmpty();
while (p != 1)
{
postfix[t]= POP(S);
t++;
p = isEmpty();
}
postfix[t]='\0';
cout<<" Persamaan postfix = "<<postfix<<endl;
getch();
}
Gambar 9.4 Fungsi mengubah infix menjadi postfix
b. Operator, maka
i. R = pop(stack); L = pop(stack)
ii. lakukan operasi, push hasilnya ke stack
4. Hasil ekspresi = pop Stack.
5. Jika stack tidak kosong, tampilkan error message.
Yang perlu diperhatikan pada algoritma di atas adalah pada langkah 3.b, melakukan
operasi untuk 2 operan dan menyimpannya lagi ke stack. Dengan memperhatikan program
yang telah dibuat, array dan stack yang digunakan bertipe char, sehingga hanya dapat
menyimpan sebuah karakter. Dengan demikian, untuk memudahkan pemrograman, maka
nilai maupun hasil evaluasi, hanya berupa 1 digit angka, yaitu angka 0 sampai 9. Untuk
digit yang lebih banyak perlu digunakan array of string dan memerlukan fungsi khusus
untuk mengubah string menjadi angka atau sebaliknya.
Untuk melakukan operasi aritmetika terhadap 2 operan, perlu dikonversi dulu angka
yang bertipe char menjadi angka yang bertipe integer. Konversi ini dilakukan oleh built in
function atoi(char). Setelah dilakukan operasi aritmetika, hasilnya dikonversi kembali
menjadi angka yang bertipe char dengan menggunakan built in function itoa(int,char,base)
sehingga dapat disimpan kembali dalam stack. Fungsi yang dibuat hanya dapat digunakan
untuk operator tambah, kurang dan kali (+, - dan *). Untuk operator lain dapat ditambahkan
pada fungsi Opr(o,a,b) di bawah ini.
return(d);
}
Fungsi selengkapnya untuk mengevaluasi sebuah persamaan postfix dapat dilihat pada
program 9.6 di bawah ini.
void eval()
{
char eksp[N];
char ki, ka, x, y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi postfix = ";
cin>>eksp;
cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (isdigit(x)) // jika berupa angka, masukkan ke stack
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*')
{ // jika berupa operator maka
ka = POP(S); // pop stack 2 kali dan lalukan
ki = POP(S); // operasi aritmetika
y = opr(x,ki,ka);
PUSH(S,y); // simpan hasilnya ke stack
}
}
cout<<"Selesai ekspresi"<< endl;
Temp = POP(S);
if (isEmpty() == 1)
cout<<"Hasil evaluasi = "<<Temp<<endl;
else
cout<<"Persamaan postfix salah"<<endl;
1. Buatlah main program dan buatlah menu untuk memanggil fungsi untuk memeriksa
pasangan tanda kurung, mengubah infix menjadi postfix dan mengevaluasi postfix.
2. Lengkapi fungsi cek, fungsi infix, fungsi opr dan fungsi eval sehingga dapat
mengenali operator bagi dan pangkat.
3. Lengkapi fungsi cek, fungsi infix, fungsi opr dan fungsi eval sehingga dapat
mengenali operator unary.
4. Dalam program terpisah, ubahlah fungsi opr dan fungsi eval sehingga dapat
mengkonversi ekspresi postfix menjadi infix.
#include<iostream>
#include<string.h>
#define N 100
#define true 1
#define false 0
int Tos;
char S[N];
void Inisialisasi()
{
Tos=0;
}
int isEmpty()
{
if (Tos == 0)
return (1);
else
return (0);
}
return ('#');
}
return (S[Tos]);
}
void pasangan()
{
char eksp[N];
char s, t;
int i,p;
if (isEmpty() == 1)
cout<<"Pasangan tanda kurung sesuai"<<endl;
else
cout<<"Tanda kurung tidak berpasangan"<<endl;
}
else
return (0); // isi top of stack = '(' ||
'+'
break;} // || '-' || empty
case '/':{ if (b == '*' ||b == '/' || b =='^')
return(1);
else
return (0);
break;}
case '^':{ if (b == '^')
return(1);
else
return (0); // isi top of stack = '(' ||
'+'
break;} // || '-' || '*' || '/' || empty
}
}
void infix()
{
char eksp[N];
char postfix[N], x,y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi Matematika = ";
cin>>eksp;
cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (x == '(')
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*'|| x =='/'|| x =='^')
{
y = TOP(S);
if (y == '#')
PUSH(S,x);
else
{ j = cek(x,y);
while (j == 1)
{
postfix[t]=POP(S);
t++;
y = TOP(S);
j = cek(x,y);
}
PUSH(S,x);
}
}
else if(x == ')')
{
Temp = POP(S);
while(Temp != '(')
{
postfix[t]=Temp;
t++;
Temp = POP(S);
}
}
else
{ postfix[t]= x ; // eksp[i] == operan
t++;
}
}
t--;
cout<<"Selesai ekspresi"<< endl;
p = isEmpty();
while (p != 1)
{
postfix[t]= POP(S);
t++;
p = isEmpty();
}
postfix[t]='\0';
cout<<" Persamaan postfix = "<<postfix<<endl;
}
void eval()
{
char eksp[N];
char ki, ka, x, y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi postfix = ";
cin>>eksp;
cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (isdigit(x))
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*'|| x =='/'|| x =='^')
{
ka = POP(S);
ki = POP(S);
y = opr(x,ki,ka);
PUSH(S,y);
}
}
cout<<"Selesai ekspresi"<< endl;
Temp = POP(S);
if (isEmpty() == 1)
cout<<"Hasil evaluasi = "<<Temp<<endl;
else
cout<<"Persamaan postfix salah"<<endl;
void main()
{
// pasangan();
infix();
// eval();
}