09. Flowchart dan pseudocode

Algoritma perlu ditulis sebelum menjadi kode. Ada dua cara menuliskannya: flowchart (gambar) dan pseudocode (tulisan). Keduanya muncul di soal OSN tingkat kabupaten, dan keduanya memaksa kamu memikirkan urutan langkah tanpa direpotkan titik koma.

Menulis algoritma lebih dulu terasa seperti pekerjaan tambahan, padahal ia menghemat waktu. Alasannya: memperbaiki langkah yang salah di kertas memerlukan satu coretan, sedangkan memperbaikinya setelah menjadi enam puluh baris C++ memerlukan membaca ulang seluruh kode sambil menebak di mana letak salahnya. Di lomba, peserta yang langsung mengetik biasanya kalah oleh peserta yang menghabiskan lima menit pertama di kertas.

Simbol flowchart

Bentuk Arti Isinya
oval mulai atau selesai Mulai, Selesai
persegi satu tindakan jumlah = jumlah + a[i]
belah ketupat keputusan, dua cabang a[i] > besar?
panah urutan pengerjaan —

Empat aturan yang membuat flowchart bisa dibaca orang lain — dan tiga di antaranya adalah kesalahan yang paling sering di lembar jawaban:

  1. Belah ketupat selalu punya tepat dua panah keluar, diberi label ya dan tidak. Cabang yang tidak diberi label membuat pembaca menebak.
  2. Satu oval Mulai dan satu oval Selesai. Semua jalur akhirnya bermuara ke oval Selesai yang sama.
  3. Setiap kotak punya tepat satu panah keluar. Kalau sebuah kotak perlu dua kemungkinan, ia harus diganti belah ketupat.
  4. Tidak ada panah yang menggantung. Panah yang tidak menuju ke mana-mana berarti ada langkah yang belum dipikirkan.

Tiga pola dasar

Setiap algoritma, sepanjang apa pun, tersusun dari tiga pola ini.

Urutan

Mulai baca a dan b jumlah = a + b cetak jumlah Selesai

Percabangan

ya tidak Mulai baca n n habis dibagi 2? cetak "genap" cetak "ganjil" Selesai

Perulangan

ya tidak Mulai baca n i = 1, jumlah = 0 i <= n? jumlah = jumlah + i i = i + 1 cetak jumlah Selesai

Panah dari i = i + 1 kembali ke belah ketupat itulah perulangannya. Tanpa panah balik, tidak ada pengulangan.

Perhatikan susunan tetap sebuah perulangan pada flowchart, karena bentuk ini selalu sama untuk perulangan apa pun:

Bagian Letaknya pada gambar
penyiapan (i = 1) kotak tepat sebelum belah ketupat
syarat lanjut (i <= n) belah ketupat
isi perulangan cabang ya
perubahan (i = i + 1) kotak terakhir sebelum panah balik
sesudah perulangan cabang tidak

Percabangan di dalam perulangan

Gabungan kedua pola itu adalah bentuk yang paling sering muncul di soal: telusuri seluruh data, dan pada setiap elemen ambil keputusan. Berikut algoritma mencari nilai terbesar.

ya tidak ya tidak Mulai baca n dan a[1..n] besar = a[1], i = 2 i <= n? a[i] > besar? besar = a[i] i = i + 1 cetak besar Selesai

Ada dua belah ketupat dengan tugas yang berbeda: yang atas mengatur berapa kali perulangan berjalan, yang bawah mengatur apa yang dikerjakan pada satu elemen. Perhatikan juga bahwa kedua cabang belah ketupat bawah bertemu kembali di kotak i = i + 1 — langkah itu harus dijalankan apa pun keputusannya, kalau tidak perulangannya tidak pernah berhenti.

Perulangan yang digambar tanpa langkah i = i + 1 adalah perulangan tak berujung. Pada gambar, kesalahan ini kelihatan jelas: tidak ada kotak yang mengubah nilai yang diperiksa belah ketupat.

Pseudocode

Pseudocode adalah algoritma yang ditulis sebagai kalimat pendek, satu langkah per baris, dengan indentasi untuk menunjukkan bagian dalam. Tidak ada aturan baku, tetapi bentuk yang dipakai buku ini:

BACA n
jumlah <- 0
UNTUK i DARI 1 SAMPAI n
    jumlah <- jumlah + i
CETAK jumlah

Kata kunci yang cukup dikuasai:

Kata kunci Arti
BACA x membaca masukan
CETAK x menulis keluaran
x <- nilai mengisi variabel
JIKA syarat ... SELAIN ITU percabangan
UNTUK i DARI a SAMPAI b perulangan dengan cacah tetap
SELAMA syarat perulangan bersyarat

Dua aturan bentuknya: satu langkah per baris, dan indentasi menunjukkan isi. Baris yang menjorok ke dalam berarti berada di dalam perulangan atau percabangan tepat di atasnya. Karena tidak ada kurung kurawal, indentasi itulah satu-satunya penanda — jadi menuliskannya dengan rapi bukan soal keindahan.

Bandingkan dua pseudocode yang hanya berbeda indentasinya:

jumlah <- 0
UNTUK i DARI 1 SAMPAI n
    jumlah <- jumlah + i
    CETAK jumlah
jumlah <- 0
UNTUK i DARI 1 SAMPAI n
    jumlah <- jumlah + i
CETAK jumlah

Yang pertama mencetak n baris, yang kedua mencetak satu baris. Soal OSN tingkat kabupaten memang gemar menguji perbedaan sehalus ini.

Contoh yang lebih panjang — mencari nilai terbesar:

BACA n
BACA a[1..n]
besar <- a[1]
UNTUK i DARI 2 SAMPAI n
    JIKA a[i] > besar
        besar <- a[i]
CETAK besar

Dari pseudocode ke C++

Terjemahannya nyaris baris per baris:

Pseudocode C++
BACA n cin >> n;
CETAK besar cout << besar << "\n";
besar <- a[1] besar = a[0];
UNTUK i DARI 2 SAMPAI n for (int i = 1; i < n; i++)
JIKA a[i] > besar if (a[i] > besar)
SELAMA sisa > 0 while (sisa > 0)
a[i] a[i - 1] bila pseudocode mulai dari 1

Perhatikan pergeseran indeks: pseudocode di buku ini menulis array mulai dari 1 (seperti soal OSN), sedangkan C++ mulai dari 0. Salah satu sumber kesalahan paling sering saat menerjemahkan.

Ada dua cara menanganinya, dan keduanya sah asal dipakai konsisten:

  • Geser semuanya: a[1] pada pseudocode menjadi a[0] pada kode, dan UNTUK i DARI 1 SAMPAI n menjadi for (int i = 0; i < n; i++).
  • Biarkan indeks 0 kosong: baca data ke a[1] sampai a[n], dan tulis for (int i = 1; i <= n; i++). Arraynya cukup dibuat satu kotak lebih besar.

Cara kedua sering dipilih di lomba justru karena menghilangkan pergeseran itu: kode dan soal memakai penomoran yang sama, sehingga rumus seperti "elemen ke-i dan ke-i+1" bisa disalin apa adanya.

Membaca pseudocode orang lain

Latihan yang dipakai OSN tingkat kabupaten berbentuk terbalik: pseudocode diberikan, keluarannya yang ditanyakan. Coba potongan ini sebelum membaca lanjutannya:

n <- 5
hasil <- 1
SELAMA n > 1
    hasil <- hasil * n
    n <- n - 1
CETAK hasil

Telusuri dengan tangan: hasil berturut-turut menjadi 5, lalu 20, lalu 60, lalu 120, dan n berhenti di 1. Keluarannya 120, yaitu 5!. Bab 10 mengajarkan cara membuat tabel penelusuran seperti ini secara sistematis supaya tidak ada langkah yang terlewat.

Buka exercises/09/01-terbesar.cpp. Bandingkan setiap barisnya dengan pseudocode di atas, lalu ubah agar mencetak nilai terkecil — cukup ganti dua tempat.

Kapan memakai yang mana

  • Flowchart untuk algoritma pendek dengan percabangan rumit. Bentuk gambarnya memperlihatkan cabang yang terlewat.
  • Pseudocode untuk algoritma dengan perulangan bersarang atau banyak langkah. Menggambar tiga perulangan bersarang menjadi gambar yang tidak terbaca; menuliskannya cukup enam baris.

Di lembar jawaban OSN tingkat kabupaten, soal sering menyajikan pseudocode lalu bertanya "apa keluarannya?". Kemampuan membaca pseudocode orang lain sama pentingnya dengan menulisnya — dan itu latihan Bab 10.

Buka exercises/09/02-pseudocode-ke-kode.cpp. Di bagian atasnya ada pseudocode sebagai komentar, di bawahnya terjemahan C++-nya. Jalankan, lalu ubah pseudocode-nya menjadi "cetak bilangan ganjil saja" dan sesuaikan kodenya.

Pekerjaan rumah

Soal 1 dan 2 dikerjakan di kertas.

Soal 1 — Gambar flowchart

Gambar flowchart untuk algoritma berikut: baca n, lalu baca n bilangan, cetak berapa banyak yang bernilai negatif. Flowchart-mu harus punya satu oval mulai, satu oval selesai, satu belah ketupat untuk perulangan, satu belah ketupat untuk pemeriksaan negatif, dan satu panah balik.

Soal 2 — Tulis pseudocode

Tulis pseudocode untuk: baca n, cetak semua pembagi n dari 1 sampai n, lalu cetak jumlah pembagi tersebut. Gunakan kata kunci dari tabel di bab ini.

Soal 3 — Baca flowchart, tulis kodenya

Buka exercises/09/homework/03-dari-flowchart.cpp. Di bagian atas file ada flowchart yang digambar dengan karakter teks. Tulis kode C++ yang menjalankan algoritma itu persis.

Soal 4 — Baca pseudocode, ramalkan keluarannya

Buka exercises/09/homework/04-ramalkan.cpp. Ada tiga potongan pseudocode di dalam komentarnya. Untuk setiap potongan, tulis dulu tebakanmu di komentar, baru terjemahkan ke kode dan jalankan untuk memeriksa.

Tantangan — Perbaiki flowchart yang salah

Buka exercises/09/homework/05-flowchart-salah.cpp. Flowchart dalam komentar seharusnya mencetak bilangan prima dari 2 sampai n, tetapi ada tiga kesalahan: satu cabang belah ketupat tidak diberi label, satu langkah penambahan terlewat, dan satu panah balik menuju kotak yang keliru. Temukan ketiganya, tulis perbaikannya sebagai komentar, lalu tulis kode yang benar.

Kesalahan yang paling sering

Kesalahan Akibatnya
cabang belah ketupat tanpa label pembaca tidak tahu cabang mana yang mana
tidak ada kotak yang mengubah nilai yang diperiksa perulangan tak berujung
panah balik menuju kotak penyiapan nilai disetel ulang terus, tak berujung
dua panah keluar dari kotak biasa bukan flowchart yang sah
indentasi pseudocode tidak konsisten isi perulangan menjadi ambigu
UNTUK i DARI 1 SAMPAI n diterjemahkan i < n satu putaran hilang

Tips OSN

Soal "ramalkan keluaran" adalah soal gratis kalau ditelusuri dengan tabel. Jangan membacanya dalam kepala. Buat tabel di kertas coretan: satu kolom per variabel, satu baris per putaran. Cara ini memakan waktu setengah menit dan hampir tidak pernah salah, sedangkan menebak dari membaca hampir selalu salah di putaran terakhir.

Putaran i jumlah
awal 1 0
1 2 1
2 3 3

Periksa dua tempat yang paling sering menjebak: nilai variabel sesudah perulangan berakhir, dan apakah CETAK berada di dalam atau di luar perulangan. Perbedaan indentasi satu tingkat mengubah jawaban dari satu baris menjadi n baris.

Perhatikan batas perulangan. UNTUK i DARI 1 SAMPAI n mencakup n, sedangkan for (int i = 1; i < n; i++) tidak. Kesalahan satu putaran ini adalah penyebab Wrong Answer yang paling sering pada soal terjemahan.

Pseudocode pada soal memakai indeks mulai 1. Soal OSN hampir selalu menomori data dari 1, sedangkan array C++ mulai dari 0. Tentukan cara penanganannya sekali di awal — geser semuanya, atau biarkan indeks 0 kosong — lalu pakai satu cara itu saja sampai selesai. Mencampur keduanya di satu program adalah sumber kesalahan yang sangat sulit ditemukan.

Rancangan di kertas bukan pemborosan waktu. Lima menit menulis pseudocode menghemat setengah jam mengejar kesalahan logika, karena kesalahan rancangan terlihat sebagai kalimat yang janggal, bukan sebagai angka yang salah pada kasus uji ke-37. Yang perlu digambar bukan seluruh program, melainkan bagian yang belum jelas.

Flowchart berguna untuk memeriksa alur, bukan untuk menulis kode. Di lomba, gambar flowchart lengkap tidak sepadan dengan waktunya. Yang dipakai adalah bentuk ringkasnya: tiga sampai lima kotak untuk memastikan setiap cabang punya jalan keluar dan setiap perulangan punya syarat berhenti.

Kalau sebuah perulangan terasa membingungkan, tuliskan invarian-nya: satu kalimat yang selalu benar di awal setiap putaran, misalnya "jumlah berisi total dari a[1] sampai a[i-1]". Kalimat itu langsung menunjukkan nilai apa yang harus dicetak setelah perulangan selesai.

Ringkasan

  • Flowchart memakai oval untuk mulai/selesai, persegi untuk tindakan, belah ketupat untuk keputusan, dan panah untuk urutan.
  • Belah ketupat punya tepat dua panah keluar berlabel ya dan tidak; perulangan ditandai panah balik menuju belah ketupatnya.
  • Pseudocode menulis satu langkah per baris dan memakai indentasi untuk menunjukkan isi perulangan atau percabangan.
  • Kata kunci yang dipakai buku ini: BACA, CETAK, <-, JIKA, SELAIN ITU, UNTUK ... DARI ... SAMPAI ..., SELAMA.
  • Flowchart cocok untuk percabangan rumit, pseudocode untuk perulangan bersarang dan algoritma panjang.
  • Terjemahannya ke C++ nyaris baris per baris; yang perlu diawasi adalah pergeseran indeks array dari 1 menjadi 0.

Latihan bergaya OSN

Dua soal pertama dikerjakan di kertas lebih dulu, seperti soal analitik yang muncul di seleksi tingkat awal: yang diuji bukan kecepatan mengetik, melainkan ketelitian menelusuri. Soal ketiga baru dikerjakan di komputer, tetapi tulis pseudocode-nya lebih dulu.

Kerangkanya ada di exercises/09/osn/.

Soal 1 — Telusuri Pseudocode

Perhatikan pseudocode berikut:

BACA n
a <- 0
b <- 1
UNTUK i DARI 1 SAMPAI n
    JIKA i habis dibagi 3
        a <- a + i
    SELAIN ITU
        b <- b * 2
CETAK a
CETAK b

Jawab tanpa menjalankan program:

a. Apa yang dicetak untuk n = 10? b. Apa yang dicetak untuk n = 1? c. Dengan kalimat sendiri, apa arti nilai a dan nilai b secara umum? d. Mulai dari n berapa nilai b melewati batas int?

Cara mengerjakannya. Buat tabel dengan kolom i, a, dan b, lalu isi satu baris per putaran. Untuk bagian (c), perhatikan berapa kali masing- masing cabang dimasuki, bukan nilainya satu per satu.

Sesudah menjawab di kertas, periksa dengan exercises/09/osn/solutions/01-telusuri.cpp.

Soal 2 — Baca Flowchart

Flowchart berikut membaca satu bilangan bulat N dan mencetak satu bilangan.

ya tidak Mulai baca n p = 1 p * 2 <= n? p = p * 2 cetak p Selesai

a. Apa yang dicetak untuk N = 100? b. Apa yang dicetak untuk N = 1? c. Dengan satu kalimat, apa yang dihitung flowchart ini? d. Tulis kodenya dalam C++, lalu jalankan untuk N = 10¹⁸.

Format masukan. Satu baris berisi bilangan bulat N.

Format keluaran. Satu baris berisi satu bilangan bulat.

Batasan. 1 ≤ N ≤ 10¹⁸.

Kerangkanya: exercises/09/osn/02-pangkat-dua.cpp

Soal 3 — Deret Gunung

Sebuah barisan disebut barisan gunung kalau ia naik tegas sampai satu puncak, lalu turun tegas sampai akhir. Naik tegas berarti setiap angka lebih besar daripada angka sebelumnya; turun tegas berarti setiap angka lebih kecil daripada angka sebelumnya. Puncaknya tidak boleh berada di ujung: harus ada bagian yang naik dan bagian yang turun.

Format masukan. Baris pertama berisi bilangan bulat N. Baris kedua berisi N bilangan bulat A₁ A₂ … A_N.

Format keluaran. Satu baris berisi YA kalau barisannya barisan gunung, atau TIDAK kalau bukan.

Batasan.

  • 3 ≤ N ≤ 200.000
  • 1 ≤ Aᵢ ≤ 10⁹

Contoh masukan

5
1 3 7 4 2

Contoh keluaran

YA

Penjelasan. Barisan naik dari 1 ke 3 ke 7, lalu turun ke 4 dan 2. Barisan 1 2 3 4 bukan barisan gunung karena tidak pernah turun, dan barisan 3 3 4 2 1 bukan karena dua angka pertamanya sama — naiknya tidak tegas.

Tulis pseudocode-nya lebih dulu di kertas. Petunjuk: hanya perlu dua perulangan yang berjalan berurutan pada penunjuk yang sama, bukan dua perulangan bersarang.

Kerangkanya: exercises/09/osn/03-deret-gunung.cpp

Bingung atau sudah selesai? Buka halaman pembahasan PR.