Pertemuan 10 Pemrograman TerstrukturPemrograman Terstruktur · Algoritma rekursif secara umum dapat...

34
Pertemuan 10 Pemrograman Terstruktur Pemrograman Terstruktur REKURSI

Transcript of Pertemuan 10 Pemrograman TerstrukturPemrograman Terstruktur · Algoritma rekursif secara umum dapat...

Pertemuan 10Pemrograman TerstrukturPemrograman Terstruktur

REKURSI

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 (tracing) pada Fungsi RekursiRekursi

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);

}

Penelusuran fungsi void yang rekursirekursi

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);}

Referensi

Bab 10, “Recursion”, Problem Solving and Program Design in C, Jeri R. Hanly dan Elliot B. Koffman, Addison Wesley 2002Wesley, 2002