Fungsi Rekursi
Fungsi Rekursi adalah fungsi yang memanggil dirinya sendiri
R k i d t di k b i lt tif d i Rekursi dapat digunakan sebagai alternatif dari iterasi/perulangan (looping)
Algoritma Rekursi
Algoritma rekursif secara umum dapat dituliskan terdiri dari if statement sebagai berikut:
if this is a simple casepsolve it
elseredefine the problem using recursionredefine the problem using recursion(recursive step)
Simple case & recursive step
Simple case (base case) adalah kondisi untuk menghentikan rekursi
R i t d l h k di i t k l k k k i Recursive step adalah kondisi untuk melakukan rekursi
Contoh1: Rekursi untuk Perkalian 2 BilanganBilangan
int multiply(int m, int n){{
int ans;
if (n == 1)/* i l */ans = m; /* simple case */
elseans = m + multiply (m, n - 1);/* recursive step */
return (ans);( )}
Contoh2: Menghitung jumlah Karakter dalam suatu Stringg
int count (char ch, const char *str){
int ans;int ans;
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 */else / first character is not counted /
ans = count(ch, &str[1]);return (ans);
}
Penelusuran fungsi rekusi yang mengembalikan suatu nilaimengembalikan suatu nilai
Fungsi Rekursi untuk Perkalian 2 buah bilangan
i t lti l (i t i t )int multiply(int m, int n){
int ans;
if (n == 1)ans = m; /* simple case */
elseans = m + multiply (m, n - 1);
/* recursive step */return (ans);return (ans);
}
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 pushoperasi push dan menghapus data dengan menggunakan perintah
operasi pop
Fungsi Rekursi pada MatematikaBanyak fungsi matematika yang dapat didefinisikan dengan
rekursi.Contoh: fungsi faktorial dari n (n!), dapat didefinisikan g ( ), p
secara iteratif : 0! Adalah 1 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 faktorialProgram ://menghitung n! Menggunakan definisi rekursi//pre : n>=0
Int factorial (int n){
int ans;int ans;if (n == 0)
ans = 1; /*simple case*/elseelse
ans = n * factorial (n-1); /*recursive step*/return(ans);
}}
Penulusuran dari fact= factorial(3);factorial(3);
Fact=factorial(3);
return(ans)
n = 3ans=3 * factorial (2)6
return(ans)
n = 2ans=2 * factorial (1)
2
return(ans)
( )
n = 1ans 1 * factorial (0)
1
n = 0
return(ans)
ans=1 * factorial (0)
1
return(ans)
n 0ans=1
Iteratif untuk faktorialProgram ://menghitung n! Menggunakan iteratif//pre : n>=0
Int factorial (int n){
int i; /*variabel lokal */Product =1;
//menghitung perkalian n x (n-1) x (n-2) x ... X 2 x 1For (i=n; i>1; --i) {Product=product * i;}}
//Mengembalikan kembalian fungsiReturn(product);
}}
Persamaan dan perbedaan iteratif & rekursi adalah& rekursi adalah
Persamaan Perbedaan Persamaan Sama-sama
merupakan bentuk
Perbedaan Pada rekursi, dikenal
adanya istilah perulangan
Dilakukan pengecekan kondisi
recursive step Sedangkan pada
iteratif ada decrementpengecekan kondisi terlebih dahulu sebelum mengulang
iteratif ada decrement
Kelebihan dan kelemahan rekursi :
Kelemahan Kelebihan solusi sangatlah
Kelemahan sulit dipahami perlu stack besar
efisien dapat memecahkan
masalah yang sulit
p(stack overrun)
masalah yang sulit dengan tahapan yang mudah dan i k tsingkat
10.4 Fungsi Rekursi dengan Parameter Array dan String
10.5 Pemecahan Masalah dengan Rekursi10.6 Studi Kasus Klasik dengan Rekursi:
Tower of HanoiTower of Hanoi
Fungsi Rekursi dengan Parameter Array dan Stringg
Study Kasus: Menemukan Huruf Kapital dalam stringAnalisa
input : String (str)H f k i l ( )output : Huruf kapital (caps)
penyelesaian: if (str[0] == '\0')caps[0] = '\0'; else{if (isupper(str[0]))sprintf(caps, "%c%s",
str[0],find_caps(restcaps, &str[1]));elsefind caps(caps, &str[1]);}_ p ( p , [ ]);}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 gkapital dalam caps dan sisanya dalam str kembali.
3. Jika huruf pertama kapital, simpan sisanya dalam str.
Implementasi Implementasi#include<stdio.h>#include<ctype.h>#define STRSIZ 50
char *find_caps(char *caps, //output-string of all caps found in strconst 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"));}
char *find_caps(char *caps, const char*str){
char restcaps[STRSIZ]; //caps from reststrif (str[0] == '\0')
caps[0] = '\0'; //no lettrers in str => no caps in strcaps[0] \0 ; //no lettrers in str > no caps in strelse{
if (isupper(str[0]))sprintf(caps, "%c%s", str[0],find_caps(restcaps, &str[1]));
elsefi d ( & t [1]) }find_caps(caps, &str[1]);}return (caps);
}
Penelusuran pemanggilan untuk Fungsi Rekursi Menemukan Huruf Penelusuran pemanggilan untuk Fungsi Rekursi Menemukan Huruf Kapital
printf(...find_caps(caps, “JoJo”));
str is “JoJo”‘J’ is uppercase
sprintf(caps, “%c%s”,’J’, find_caps(restcaps, “oJo”));
return(caps) str is “oJo”
“JJ”
str is oJo‘o’ is not uppercase
find_caps(caps, “Jo”));return(caps)
str is “Jo”‘J’ is uppercase
sprintf(caps “%c%s” ’J’“J”
“J”
str is “o”‘o’ is not uppercase
find_caps(caps, “ ”));return(caps)
sprintf(caps, %c%s , J , find_caps(restcaps, “o”));
return(caps)
“ “
return(caps)
str is “ ”caps is “ ”
return(caps)
“ “
return(caps)
10.5 Pemecahan Masalah dengan RekursiKarena 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
Studi Kasus Klasik dengan Rekursi: Menara Hanoi
Menara Hanoi adalah problem di mana kita harus memindahkan balok yang mempunyai perbedaan ukuran dari suatu menara (tower) ke menara lainnya.
• ProblemA B C Problem• Memindahkan n balok dari
menara A ke menara C menggunakan menara B bila dibutuhkan
A B C
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
Analisis
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
k k ti b i tmenggunakan menara ketiga sebagai perantara. Data yang dibutuhkan : Problem inputs
int n /* jumlah balok yang dipindahkan */ Char awal /* menara awal */ Char akhir /* menara akhir atau menara yang dituju */
Ch id /* b i t */ Char mid /* menara sebagai perantara */ Problem Outputs
Daftar perpindahan balok
DesainAlgorithma1. Jika n adalah 1 maka2. 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 tidak3 Pindahkan n 1 disks dari menara awal ke menara perantara3. Pindahkan n-1 disks dari menara awal ke menara perantara dengan menggunakan menara akhir4. Pindahkan balok n dari menara awal ke menara akhir5. Pindahkan n-1 balok dari menara perantara ke menara akhir p
menggunakan menara awal. masuk rekursielse{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 dibutuhkan6. Menghitung banyaknya perpindahan yang dibutuhkanjum=pow(2,n)-1;
7. Menampilkan banyaknya perpindahanprintf("\n>>jumlah perpindahannya adalah : %d", jum);
Implementasi Menara Hanoi
#include<stdio.h>#include<math.h>#include<conio h>#include<conio.h>int n;char awal='A';char akhir='C';h id 'B'char mid='B';
void menara(char awal,char akhir,char mid,int n){
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);%c\n ,n,awal,akhir);menara(awal,mid,akhir,n-1);}
}
void main()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 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);void print_with_commas (const char *str);void print set (const char *set);void print_set (const char set);char *get_set (char *set);
int main(void){
h l t [SETSIZE] t t [SETSIZE] t th [SETSIZE]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>");p ( );get_set (set_one);
putchar ('\n');print_set (set_one);if (is_set(set_one))
printf ("is a valid set\n");lelse
printf ("is invalid\n");printf ("Enter a single character, a space, and a set>");while (isspace (ele = getchar()))get set (set one);g _ ( _ );printf ("\n%c", ele);if (is_element(ele, set_one))
printf ("is an element of");else
printf ("is not an element of");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));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))
ans = FALSE;else if (set [0] == ele)else if (set [0] == ele)
ans = TRUE;else
ans = is_element (ele, &set[1]);
return (ans);}
int is set (const char *set)int is_set (const char set){
int ans;if (is_empty(set))
ans = TRUE;l if (i l t ( t [0] & t [1]))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);return (ans);}
char *set union (char *result const char *set1 const char *set2)char set_union (char result, const char set1, const char set2){
char temp [SETSIZE];if (is_empty(set1))
strcpy (result, set2);l if (i l t ( t1 [0] t2))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);print_with_commas(set);putchar('}');
}
char *get_set (char *set){
char inset [SETSIZE];scanf ("%s", inset);strncpy (set, &inset[1], strlen (inset)-2);set [strlen (inset) - 2] = '\0';set [strlen (inset) 2] \0 ;
return (set);}