Welcome to my Blog

Selasa, 27 Mei 2014

KalkulatorPostfix

Kalkulator Postfix Dalam Bahasa Pascal


Hadi Pranoto
By : @hadipranoto_

Screenshot of Postfix Calculator



Program Kalkulator_Postfix;
{I.S: Program penghitung notasi infix}
{F.S: Program dalam keadaan siap digunakan}
uses crt;
 
Const
     Max = 150;
 
type

    ArrChar=array[1..max] of char;
    
    ArrValue=array[1..max] of real;

    StackOfChar=record
           Data:ArrChar;
           Top:byte;
           end;

    StackOfValue=record
           Data:ArrValue;
           Top:byte;
           end;

    K_string=string[max];


var
   TumpukanData  : StackOfChar;
   TumpukanHasil : StackOfValue;


   Infix,ekspresiP : K_string;
   i,TopA : byte;
   Hasil  : real;
   Lagi   : char;

   Procedure Inisialisasi(var TData:StackOfChar; var THasil:StackOfValue;var TopA:byte);
   {I.S: Memberi harga awal penunjuk top}
   {F.S: penunjuk top bernilai nol}
   begin
        TData.top:=0;
        THasil.top:=0;
        TopA:=0;
   end;
 
   Function Kosong(Top: byte):boolean;
   {I.S : Penunjuk Top terdefinisi}
   {F.S : Mengecek status Top kosong atau tidak}
   begin
        Kosong:=false;
        if(Top=0)then
             Kosong:=true;
   end;

   Function Penuh(Top:byte):boolean;
   {I.S : Penunjuk Top terdefinisi}
   {F.S : Mengecek status Top penuh atau tidak}
   begin
        Penuh:=false;
        if(Top=max)then
             Penuh:=true;
   end;

   Function Panjang(Kalimat:K_string):integer;
   {I.S: Kalimat sudah terdefinisi}
   {F.S: Mengembalikan nilai dari panjang kalimat}
   begin
        Panjang:=length(kalimat);
   end;
 
   Function Salah(Kalimat:K_string):boolean;
   {I.S: Kalimat sudah terdefinisi}
   {F.S: Mengecek status kalimat infix salah atau tidak}
   var
        i : integer;
        IsiOperator : set of char;
 
   begin
        IsiOperator:=['^']+['*']+['/']+['+']+['-'];

        Salah:=false;
        for i:=1 to Panjang(kalimat) do
        begin
             if((kalimat[i] in IsiOperator) and (kalimat[i+1] in IsiOperator))
             or (kalimat[Panjang(kalimat)] in IsiOperator) or (kalimat[1] in IsiOperator)then
                begin
                     Salah:=true;
                end;
        end;
   end;
 
   Function Kasta(Opr:Char):byte;
   {F.S: operator sudah terdefinisi}
   {I.S: Mengembalikan nilai tingkatan operator }
   begin
        case opr of
             '^'     : kasta:=3;
             '*','/' : kasta:=2;
             '+','-' : kasta:=1;
        end;
   end;
 
   Function Pangkat(m,n:real):real;
   {I.S : peubah m dan n sudah terdefinisi}
   {F.S : Menghitung nilai dari m pangkat n}
   begin
        if(n = 0)then
             Pangkat := 1
        else
             Pangkat := m * Pangkat(m,n-1);

   end;
 
   Procedure Proses(var Infix:k_string);
   {I.S: Notasi infix dibaca dari piranti masukan}
   {F.S: Notasi infix disimpan jika betul penulisannya}
   var
        stop : boolean;

   begin
        stop:=false;
        while(not stop) do
        begin
             if(Salah(Infix)) or (Infix = '')then
               begin
                    writeln('Notasi yang anda masukan salah!');
               end
             else
                    stop:=true;
        end;
   end;
 
   Procedure Push(var Tumpukan:StackOfChar; elemen:char);
   {I.S: Menambahkan data baru kedalam stack paling atas}
   {F.S: Data baru ditambahkan kedalam stack jika tidak penuh}
   begin
       if (not penuh(tumpukan.top)) then
          begin
              Tumpukan.top:=Tumpukan.top+1;
              Tumpukan.data[tumpukan.top]:=elemen;
       end;
   end;
 
   Procedure Pop(var Tumpukan:StackOfChar; var elemen:char);
   {I.S: Mengeluarkan data teratas jika stack tidak kosong}
   {F.S: Data dikeluarkan dari stack jika tidak kosong}
   begin
     if (not kosong(tumpukan.top)) then
        begin
           Elemen:=Tumpukan.data[tumpukan.top];
           Tumpukan.top:=Tumpukan.top-1;
     end;
   end;
 
   Procedure Tampungdata(var TopA:byte; var kalimat:k_string; elemen:char);
   {I.S: Menyisipkan elemen kedalam peubah kalimat}
   {F.S: Menyimpan hasil akhir suatu notasi tertentu}
   begin
        TopA:=TopA+1;
        Kalimat[TopA]:=elemen;
   end;
 
   Procedure NotasiPostfix(infix:k_string; Tumpukan:StackOfChar;var ekspresiP: k_string; var TopA:byte);
   {I.S: Infix dan tumpukan sudah terdefinisi sebelumnya}
   {F.S: ekspresi P menyimpan hasil perubahan notasi dari infix menjadi postfix}
   var
      i : integer;
      IsiOperator : set of char;
      Simbol,elemen : char;

   begin
        IsiOperator := ['^']+['*']+['/']+['+']+['-'];
        Push(Tumpukan,'(');
        Infix[Panjang(Infix)+1]:=')';
 
        for i:=1 to Panjang(Infix)+1 do
        begin
             Simbol:=Infix[i];
 
             if(Simbol = '(') then
                   Push(Tumpukan,Simbol)
             else
             if(Simbol = ')')then
                begin
                    repeat
                         Pop(Tumpukan,elemen);
                         Tampungdata(TopA,EkspresiP,elemen);
                    until(Tumpukan.data[tumpukan.top] = '(');
                    Pop(Tumpukan,elemen);
                end
             else
             if(Simbol in IsiOperator) then
                begin
                     //jika tingkatan operator lebih tinggi daripada simbol maka pop
                     while(Tumpukan.data[tumpukan.top] <> '(') and (Kasta(Tumpukan.data[tumpukan.top])>=Kasta(Simbol)) do
                     begin
                           Pop(Tumpukan,elemen);
                           Tampungdata(TopA,EkspresiP,elemen);
                     end;
                     //jika tingkatan operator lebih rendah daripada simbol maka push
                     Push(Tumpukan,Simbol);
                end
             else
                Tampungdata(TopA,EkspresiP,Simbol);
        end;

   end;


  {daerah subrutin hitung postfix}
   Procedure PushNilai(var Tumpukan:StackOfValue; data:real);
   {I.S: Memasukan data kedalam Tumpukan}
   {F.S: Tumpukan berisi data baru }
   begin
        if (not penuh(tumpukan.top)) then
          begin
               Tumpukan.top:=Tumpukan.top+1;
               Tumpukan.data[tumpukan.top]:=data;
          end;
     end;
 
   
   Procedure PopNilai(var Tumpukan:StackOfValue; var data:real);
   {I.S: Mengeluarkan data ke-top jika stack tidak kosong}
   {F.S: Data baru dikeluarkan dari stack jika tidak kosong}
   begin
        if (not kosong(tumpukan.top)) then
          begin
               Data:=Tumpukan.data[tumpukan.top];
               Tumpukan.top:=Tumpukan.top-1;
          end
   end;


   Procedure HitungPostfix(var EkspresiP: k_string; Tumpukan:StackOfValue; var hasil:real);
   {I.S: Mengeksekusi notasi postfix}
   {F.S: Peubah hasil menyimpan nilai hasil eksekusi notasi postfix }
   var
        i,y : byte;
        IsiOperator : set of char;
        Simbol : char;
        a,b,angka,hitung : real;
 
   begin
        y:=11;

        IsiOperator := ['^']+['*']+['/']+['+']+['-'];
        EkspresiP[TopA+1] := ')';

        for i:=1 to topA+1 do
        begin
             Simbol:=EkspresiP[i];

             if(Simbol in IsiOperator)then
                begin
                     PopNilai(Tumpukan,angka);
                     b:=angka;
                     PopNilai(Tumpukan,angka);
                     a:=angka;
 
                     case Simbol of
                          '^' : hitung := Pangkat(a,b);
                          '*' : hitung := a*b;
                          '/' : hitung := a/b;
                          '+' : hitung := a+b;
                          '-' : hitung := a-b;
                     end;
 
                     PushNilai(Tumpukan,hitung);
                end
             else
             if(Simbol = ')') then
                begin
                     PopNilai(Tumpukan,angka);
                     hasil:=angka;
                end
             else
                begin
                     gotoxy(20,y);write('Masukkan Nilai ',Simbol,' : '); readln(angka);
                     PushNilai(Tumpukan,angka);
                     y:=y+1;
             end;
        end;
   end;
 

begin
     repeat
           clrscr;
           textcolor(11);
           gotoxy(20,1); write ('             www.hadipranoto.tk');
           gotoxy(20,4); write ('=============================================');
           gotoxy(20,5); write ('+            Kalkulator Postfix             +');
           gotoxy(20,6); write ('=============================================');

           textcolor(white);
           Inisialisasi(TumpukanData,TumpukanHasil,TopA);

           gotoxy(20,8);write('Masukan Notasi Infix : '); readln(Infix);
           proses (infix);


           NotasiPostfix(Infix,Tumpukandata,ekspresiP,TopA);
           textcolor(yellow);
           gotoxy(20,9);write('Notasi Postfix       : ');
           if(Kosong(Tumpukandata.top))then
              begin
                   for i:=1 to TopA do
                   begin
                        write(EkspresiP[i]);
                   end;
           end;
           writeln;
           textcolor(white);
           HitungPostfix(EkspresiP,TumpukanHasil,hasil);
           textcolor(yellow);
           gotoxy(20,20);writeln('Value = ',hasil:0:2);

           textcolor(11);
           gotoxy(20,21); write ('=============================================');

           gotoxy(20,22);write('Apakah akan mengitung lagi (y/t) : '); readln(lagi);
     until(lagi = 'T') or (lagi = 't');
end.

Tidak ada komentar:

Posting Komentar