Anda di halaman 1dari 34

Pertemuan 10

Pemrograman Procedural Pemrograman Procedural


REKURSI
Fungsi Rekursi
Fungsi Rekursi adalah fungsi yang
memanggil dirinya sendiri
Rekursi dapat digunakan sebagai alternatif
dari iterasi/perulangan (looping) dari iterasi/perulangan (looping)
Algoritma Rekursi
Algoritma rekursif secara umum dapat
dituliskan terdiri dari if statement sebagai
berikut:
if this is a simple case
solve it
else
redefine the problem using recursion
(recursive step)
Simple case & recursive step
Simple case (base case) adalah kondisi
untuk menghentikan rekursi
Recursive step adalah kondisi untuk
melakukan rekursi melakukan rekursi
int multiply(int m, int n)
{
int ans;
Contoh1: Rekursi untuk Perkalian 2
Bilangan
if (n == 1)
ans = m; /* simple case */
else
ans = m + multiply (m, n - 1);/* recursive step */
return (ans);
}
int count (char ch, const char *str)
{
int ans;
if (str[0] == \0) /* simple case */
Contoh2: Menghitung jumlah Karakter
dalam suatu String
if (str[0] == \0) /* simple case */
ans = 0;
else /* redefine problem using recursion */
if (ch == str[0]) /* first character must be counted */
ans = 1 + count (ch, &str[1]);
else /* first character is not counted */
ans = count(ch, &str[1]);
return (ans);
}
Penelusuran (tracing) pada
Fungsi Rekursi Fungsi Rekursi
Penelusuran fungsi rekusi yang
mengembalikan suatu nilai
Fungsi Rekursi untuk Perkalian 2
buah bilangan
int multiply(int m, int n)
{
int ans; int ans;
if (n == 1)
ans = m; /* simple case */
else
ans = m + multiply (m, n - 1);
/* recursive step */
return (ans);
}
Penelusuran fungsi void yang rekursi
parameter and local Variable
Stacks
stack adalah Struktur data dimana data
yang terkhir masuk adalah data yang akan
diproses terlebih dahulu.
Stack biasanya dimplementasikan dengan Stack biasanya dimplementasikan dengan
menggunakan sebuah array.
dalam stack kita bisa menambah data
dengan perintah operasi push
dan menghapus data dengan
menggunakan perintah operasi pop
Fungsi Rekursi pada
Matematika
Banyak fungsi matematika yang dapat didefinisikan dengan
rekursi.
Contoh: fungsi faktorial dari n (n!), dapat didefinisikan
secara iteratif :
0! Adalah 1
n! Adalah n x (n-1)!, untuk n>0 n! Adalah n x (n-1)!, untuk n>0
Misal: 4! Adalah 4 x 3!, yang artinya 4 x 3 x 2 x 1, atau 24
Fungsi rekursi untuk faktorial
Program :
//menghitung n! Menggunakan definisi rekursi
//pre : n>=0
Int factorial (int n)
{
int ans;
if (n == 0)
ans = 1; /*simple case*/
else
ans = n * factorial (n-1); /*recursive step*/
return(ans);
}
Penulusuran dari fact= factorial(3);
return(ans)
n = 3
ans=3 * factorial (2)
Fact=factorial(3);
2
6
return(ans)
n = 2
ans=2 * factorial (1)
return(ans)
n = 0
ans=1
return(ans)
n = 1
ans=1 * factorial (0)
1
1
2
Iteratif untuk faktorial
Program :
//menghitung n! Menggunakan iteratif
//pre : n>=0
Int factorial (int n)
{
int i; /*variabel lokal */
Product =1; Product =1;
//menghitung perkalian n x (n-1) x (n-2) x ... X 2 x 1
For (i=n; i>1; --i) {
Product=product * i;
}
//Mengembalikan kembalian fungsi
Return(product);
}
Persamaan dan perbedaan iteratif
& rekursi adalah
Persamaan
Sama-sama
merupakan bentuk
perulangan
Dilakukan
Perbedaan
Pada rekursi, dikenal
adanya istilah
recursive step
Sedangkan pada Dilakukan
pengecekan kondisi
terlebih dahulu
sebelum mengulang
Sedangkan pada
iteratif ada decrement
Kelebihan dan kelemahan rekursi :
Kelebihan
solusi sangatlah
efisien
dapat memecahkan
Kelemahan
sulit dipahami
perlu stack besar
(stack overrun)
dapat memecahkan
masalah yang sulit
dengan tahapan
yang mudah dan
singkat
10.4 Fungsi Rekursi dengan Parameter
Array dan String
10.5 Pemecahan Masalah dengan Rekursi
10.6 Studi Kasus Klasik dengan Rekursi:
Tower of Hanoi
Fungsi Rekursi dengan Parameter Array dan String
Study Kasus: Menemukan Huruf Kapital dalam string
Analisa
input : String (str)
output : Huruf kapital (caps)
penyelesaian: if (str[0] == '\0')
caps[0] = '\0';
else{ else{
if (isupper(str[0]))
sprintf(caps, "%c%s",
str[0],find_caps(restcaps, &str[1]));
else
find_caps(caps, &str[1]);}
return (caps);
Desain
1. Jika string kosong, maka string kosong tersebut akan disimpan
dalam caps.
2. Jika huruf pertama dari string adalah huruf kapital, simpan huruf
kapital dalam caps dan sisanya dalam str kembali.
3. Jika huruf pertama kapital, simpan sisanya dalam str. 3. Jika huruf pertama kapital, simpan sisanya dalam str.
Implementasi
#include<stdio.h>
#include<ctype.h>
#define STRSIZ 50
char *find_caps(char *caps, //output-string of all caps found in str
const char*str); //input-string of from which to caps extract caps
void main()
{
char caps[STRSIZ];
printf("Capital letters in JoJo are %s\n",find_caps(caps, "JoJo")); printf("Capital letters in JoJo are %s\n",find_caps(caps, "JoJo"));
}
char *find_caps(char *caps, const char*str)
{
char restcaps[STRSIZ]; //caps from reststr
if (str[0] == '\0')
caps[0] = '\0'; //no lettrers in str => no caps in str
else{
if (isupper(str[0]))
sprintf(caps, "%c%s", str[0],find_caps(restcaps, &str[1]));
else
find_caps(caps, &str[1]);}
return (caps);
}
Penelusuran pemanggilan untuk Fungsi Rekursi Menemukan Huruf
Kapital
10.5 Pemecahan Masalah dengan Rekursi
Karena di dalam C tidak ada representasi dari himpunan struktur
data, kita akan mengimplementasikan operasi pada himpunan
dengan string sebagai himpunan.
Study Kasus: Operasi pada Himpunan

Menara Hanoi adalah problem di mana kita harus memindahkan


balok yang mempunyai perbedaan ukuran dari suatu menara
(tower) ke menara lainnya.
Studi Kasus Klasik dengan Rekursi
: Menara Hanoi
Problem
Memindahkan n balok dari
menara A ke menara C
A B C
menara A ke menara C
menggunakan menara B bila
dibutuhkan.
Hal yang harus dicermati :
Hanya satu buah balok saja
yang dapat dipindahkan
dalam satu waktu
Balok yang lebih besar tidak
boleh diletakkan di atas balok
yang lebih kecil
Solusi dari menara hanoi terdiri dari daftar pemindahan
balok secara individual.
Kita membutuhkan fungsi rekursi yang dapat digunakan
untuk mencetak instruksi untuk memindahkan balok-
balok dari menara awal ke menara yang dituju
menggunakan menara ketiga sebagai perantara.
Data yang dibutuhkan :
Analisis
Data yang dibutuhkan :
Problem inputs
int n /* jumlah balok yang dipindahkan */
Char awal /* menara awal */
Char akhir /* menara akhir atau menara yang dituju */
Char mid /* menara sebagai perantara */
Problem Outputs
Daftar perpindahan balok
Algorithma
1. Jika n adalah 1 maka
2. Pindahkan balok satu dari menara awal ke menara akhir
if (n==1)
printf("pindahkan balok ke-%d dari %c ke %c\n",n,awal,akhir);
else / jika tidak
3. Pindahkan n-1 disks dari menara awal ke menara perantara
dengan menggunakan menara akhir
4. Pindahkan balok n dari menara awal ke menara akhir
Desain
4. Pindahkan balok n dari menara awal ke menara akhir
5. Pindahkan n-1 balok dari menara perantara ke menara akhir
menggunakan menara awal. masuk rekursi
else
{
menara(awal,mid,akhir,n-1);
printf("pindahkan balok ke-%d dari %c ke
%c\n",n,awal,akhir);
menara(awal,mid,akhir,n-1);
}
6. Menghitung banyaknya perpindahan yang dibutuhkan
jum=pow(2,n)-1;
7. Menampilkan banyaknya perpindahan
printf("\n>>jumlah perpindahannya adalah : %d", jum);
#include<stdio.h>
#include<math.h>
#include<conio.h>
int n;
char awal='A';
char akhir='C';
char mid='B';
void menara(char awal,char akhir,char mid,int n)
Implementasi Menara Hanoi
{
if (n==1)
printf("pindahkan balok ke-%d dari %c ke
%c\n",n,awal,akhir);
else
{
menara(awal,mid,akhir,n-1);
printf("pindahkan balok ke-%d dari %c ke
%c\n",n,awal,akhir);
menara(awal,mid,akhir,n-1);
}
}
void main()
{
int jum;
printf ("Masukkan banyak balok n : ");
scanf ("%d",&n);
menara(awal,akhir,mid,n);
jum=pow(2,n)-1;
printf("\n>>jumlah perpindahannya adalah : %d", jum);
printf("\n\n\n");
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SETSIZE 65
#define TRUE 1
#define FALSE 0
int is_empty (const char *set);
int is_element (char ele, const char *set);
int is_set (const char *set);
int is_subset (const char *sub,const char *set);
char *set_union (char *result, const char *set1, const char *set2); char *set_union (char *result, const char *set1, const char *set2);
void print_with_commas (const char *str);
void print_set (const char *set);
char *get_set (char *set);
int main(void)
{
char ele, set_one[SETSIZE], set_two[SETSIZE], set_three[SETSIZE];
printf ("A set is entered as a string of up to %d letters\n", SETSIZE-3);
printf ("and digits enclosed in {}");
printf ("for example, {a, b, c} is entered as {abc}\n");
printf ("enter a set to test validation function>");
get_set (set_one);
putchar ('\n');
print_set (set_one);
if (is_set(set_one))
printf ("is a valid set\n");
else
printf ("is invalid\n");
printf ("Enter a single character, a space, and a set>");
while (isspace (ele = getchar()))
get_set (set_one);
printf ("\n%c", ele);
if (is_element(ele, set_one))
printf ("is an element of"); printf ("is an element of");
else
printf ("is not an element of");
printf ("\nEntered two sets to test set_union>");
get_set (set_one);
get_set (set_two);
printf ("\nThe union of");
print_set (set_one);
printf (" and ");
print_set (set_two);
printf ("is");
print_set (set_union(set_three, set_one, set_two));
putchar ('\n');
return (0);
}
int is_empty (const char *set)
{
return (set [0] == '\0');
}
int is_element(char ele, const char *set)
{
int ans;
if (is_empty(set)) if (is_empty(set))
ans = FALSE;
else if (set [0] == ele)
ans = TRUE;
else
ans = is_element (ele, &set[1]);
return (ans);
}
int is_set (const char *set)
{
int ans;
if (is_empty(set))
ans = TRUE;
else if (is_element (set [0], &set [1]))
ans = FALSE;
else
ans = is_set (&set[1]);
return (ans);
}
int is_subset (const char *sub, const char *set)
{
int ans;
if (is_empty(sub))
ans = TRUE;
else if (!is_element (sub [0], set))
ans = FALSE;
else
ans = is_subset (&sub[1], set);
return (ans);
}
char *set_union (char *result, const char *set1, const char *set2)
{
char temp [SETSIZE];
if (is_empty(set1))
strcpy (result, set2);
else if (is_element (set1 [0], set2))
set_union (result, &set1 [1], set2);
else
sprintf (result, "%c%s", set1 [0], set_union (temp, &set1 [1], set2));
return (result);
}
void print_with_commas (const char *str)
{
if (strlen (str)== 1)
{
putchar (str [0]);
}
else
{
printf ("%c, ", str [0]);
print_with_commas (&str[1]);
}
}
void print_set (const char *set)
{
putchar ('{');
if (!is_empty(set))
print_with_commas(set);
putchar('}');
}
char *get_set (char *set)
{
char inset [SETSIZE];
scanf ("%s", inset); scanf ("%s", inset);
strncpy (set, &inset[1], strlen (inset)-2);
set [strlen (inset) - 2] = '\0';
return (set);
}
Referensi
Bab 10, Recursion, Problem Solving and
Program Design in C, Jeri R. Hanly dan
Elliot B. Koffman, Addison Wesley, 2002

Anda mungkin juga menyukai