Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
ครงท 8 การเขยนโปรแกรมเรยกตวเอง
Recursive หรอ Recursion • เปนการเขยนค าสงโปรแกรมทมการปฏบตงานเรยกตวเอง • โดยมการเรยกการท างาน ในล าดบกอนมาท างานในล าดบปจจบน • โดยจะเรยกล าดบกอนวนซ าไปเรอยๆ จนถงขอมลทก าหนดการสนสด
ในการเรยกตวเอง
รปแบบของฟงกชน – คาเรมตนการท างานวนรอบ โดยทวไปเปน formal
parameter ทมการสงผานคามาจากจดเรยกใช – คาสนสดการท างานเปนคาของขอมลสดทาย ทผานการเรยกตวเองโดยลด
คาลงอยางเปนล าดบ ในการเรยกฟงกชนแตละครง – ค าสงในการปฏบตงาน เรยกตวเองเปนการประมวลผลทน าผลลพธจากการ
ท างานในรอบทแลวมาปฏบตงานในรอบปจจบน เพอสงผลลพธจากการท างานไปยงจดเรยกใช
recursive • โดยทวไปการเรยกตวเองเปรยบเสมอนการท างานทกระท าซ าๆกนในรป
ของค าสง while, for • แตเราสามารถน ามาเขยนในรปแบบทเรยกตวเองโดยแทนดวยค าสง
เงอนไข การกระท าซ าจะแทนดวยการเรยกฟงกชนในล าดบกอนท างาน
รปแบบของค าสง
if the stopping case is reached
Return a value for the stopping case
else
Return a value computed by calling
the function again with different arguments.
ตวอยาง ฟงกชนหาคาแฟคตอเรยล
คาแฟคตอเรยลเปนการค านวณหาผลคณของตวเลขทมการลดตวคณอยางเปนล าดบ จนกระทงมคาเทากบ 1 ดงน 10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 5! = 5 * 4 * 3 * 2 * 1 4! = 4 * 3 * 2 * 1 1! = 1 0! = 1
ตวอยาง ฟงกชนหาคาแฟคตอเรยล
ตวอยาง ฟงกชนหาคาแฟคตอเรยล int fac (int n)
{
int sum, i;
sum = 1;
for (i = n; i > 1; i - -)
sum = sum * i;
return sum;
}
การเรยกใช output = fac (5);
int fac (int n)
{
if (n == 1 || n == 0)
return 1;
else
return n * fac (n -1);
}
ตวอยาง ฟงกชนหาคาแฟคตอเรยล int fac (int n)
{
if (n == 1 || n == 0)
return 1;
else
return n * fac (n -1);
}
ตวอยาง ฟงกชนหาคายกก าลง
• การหาคายกก าลงทมการเรยกตวเองทมการสงผานคาอารกวเมนต 2 คาเพอปฏบตงาน โดยเขยนเปนฟงกชนเรยกตวเองในการหาคา ใดๆ ก าหนดให ตวแปร x มชนดของมลเปน Double และ y เปนชนดขอมล int
ตวอยาง ฟงกชนหาคายกก าลง
double power (double x, int y)
{
if (y == 0)
return 1;
else if (y > 0)
return x * power (x, y – 1);
else
return 1/x * power (x, y + 1);
}
ตวอยางฟงกชนหาคา Fibonacci การหาคา Fibonacci นนเราตองก าหนดล าดบทตองการ และตองทราบคา
ของล าดบ 1 และ ล าดบท 2 จงจะหาคาของล าดบอนๆได ในทนถาเราก าหนดใหคาของล าดบท 1 และคาของล าดบท 2 มคาเทากบ 1 ดงนนขอมลในล าดบตอๆไปมคาดงน
1 1 2 3 5 8 13 21 …. จะเหนไดวาการท างานจะเรมจากล าดบท 3 เปนตนไป โดยคาของล าดบท 3 จะเกดจากน าคาของล าดบท 1 บวกกบคาในล าดบท 2
และท านองเดยวกน คาในล าดบท 4 จะเกดจากคาในล าดบท 2 บวกกบคาในล าดบท 3 กลาวกนงายๆคอ น าคาของล าดบกอนหนา 2 ล าดบมาบวกกนนนเอง
ตวอยางฟงกชนหาคา Fibonacci ในทน ถา n = 7
f(7) = f(5) + f(6)
13 = 5 + 8 จากการค านวณในลกษณะนนเองเราสามารถเขยนเปนฟงกชนการท างาน
โดยสรปไดดงน f(n) = 1 ถา n = 1 หรอ n = 2
= f(n – 2) + f(n – 1) ถา n > 2
int fibo (int n) { if (n = = 1||n = = 2) return 1; else return fibo(n - 2) + fibo(n - 1); }
ตวอยางฟงกชนหาคา Binary search
• วธ Binary search นนเปนการคนหาทแกปญหาท าใหเราสามารถใชเวลาเฉลยในการคนหาขอมลแตละตวเทาๆกน ถงแมวาขอมลจะอยในต าแหนงใดกตามจะพบหรอไมพบกตาม
Binary search
//Searches for target in elements first through last of array
//Precondition : The elements of table are sorted & first and last are defined. //Postcondition: IF target is in the array, return its position; otherwise, returns –1.
int binSearch (int table[], int target, int first, int last) { int mid; mid = (first + last)/2; if (first > last) //หาไมพบ return -1; else if (target = = table[mid]) //คนพบในต าแหนงกลาง return mid; else if (target < table[mid]) return binSearch (table, target, first, mid - 1); else return binSearch (table, target, mid + 1, last); }
การท างาน
• การท างานจะมเรยกตวเองโดยมการเปลยนแปลงคาของ first และ last ในการท างานแตละรอบ
• โดยแบงกลมของขอมลออกเปนสองสวน • จนกระทงพบคาทตองการอยในต าแหนงกลางของกลม
ตวอยาง ฟงกชนหอคอยฮานอย
• The Tower of Hanoi หรอ หอคอยฮานอย เปนตวอยางของการปฏบตงานในลกษณะของการเรยกตวเองทไมมการค านวณหรอสงผานคาใดๆกลบ แตเปนการปฏบตงานทกระท าในลกษณะทเปนขนตอนทคลายๆกนเปนการยายสงของจากหอหนงไปยงอกหอหนง
เราจะแบงขนตอนในการยายสงของออกเปน 3 ขนตอนใหญแตเปน 7 ขนตอนยอยดวยกน
void tower (char from, char too, char temp, int n) { if (n = = 1) cout << "Move Object 1 from tower" << from << "to tower" << too << endl; else { tower (from, temp, too, n – 1); cout <<"Move Object" <<n <<"from tower" <<from <<"to tower" <<too <<endl; tower (temp, too, from, n – 1); } } ในทน n คอจ านวนสงของทตองการยาย from คอหอทมสงของอยจ านวน n ชนโดยชนเลกซอนทบชนใหญ too คอหอทตองการยายสงของไปเกบไว temp คอหอทใชส าหรบรบฝากสนคาไวเพอขนยาย
ตวอยางโปรแกรม reverse #include<iostream>
using namespace std;
// Function prototype
void reverse( );
int main ( )
{
reverse( );
cout << endl;
return 0;
}
void reverse( )
{
char next;
cout << “Next character
or * to stop: ”;
cin >> next;
if (next != ‘*’ )
{
reverse ( );
cout << next;
}
}
ตวอยาง โปรแกรมหาคาหารรวมมาก #include<iostream> using namespace std; int gcd(int, int); int main( ) { int m, n; cout << “Enter two positive integer: “ ; cin >> m >> n; cout << endl << “Their greatest common divisor is “ << gcd(m, n) << endl; return 0; }
int gcd(int m, int n) { if (m < n) return gcd(n, m); else if(m % n == 0) return n; else return gcd(n, m % n); } เมอน าโปรแกรมไปท างานจะไดผลลพธดงน Enter two positive integer: 24 84 Their greatest common divisor is
12
ตวอยาง ฟงกชนหาผลรวมของขอมล
ตวอยาง ฟงกชนหาผลรวมของขอมล // Finds the sum of integers in an n-element array int findSum(int x[ ], int n) { if (n == 1) return x[0]; // stopping case else return x[n-1] + findSum(x, n-1); // recursive step } ผลของการเรยกใชจะเปนดงน Recursive sum is 55 Calculated sum is 55
การบาน 1
พจารณาฟงกชนตอไปน double test5(int a , int b) { double sum = 1.0 ; for (int i = 3 ; i < b ; i++) { sum = sum / (a*a) ; } } จงเขยนฟงกชนขางตนนใหมแบบเรยกตวเอง ถามการเรยกใชค าสง cout<<test5(2,6)<<endl; ผลของการท างานจะพมพคา................................ออกทางจอภาพ
การบาน 2
จงเขยนฟงกชนเรยกตวเองชอ SUM เพอใหสามารถท างานไดดงการท างานตอไปน
1 + 2/3 + 3/5 + 4/7 + … n/(n+2)
ถาผใชเรยกใช SUM(1) ผลของการท างานคอ 1 SUM(2) ผลของการท างานคอ 1 + (2/3) SUM(3) ผลของการท างานคอ 1 + (2/3) + (3/5) SUM(n) ผลของการท างานคอ 1 + (2/3) + … + n/(n+2)
การบาน 3 อาจารยอไรตองการทราบวาถาฝากเงนก าหนดเงนตน A บาท เปนจ านวน Y ป โดยอตราดอกเบยรอยละ K สมมตวาอตราดอกเบยเทากนทกป โดยฝากทบตนจนกระทงครบก าหนดจะได
เงนทงหมดเปนเงนเทาใด ทานเขยนฟงกชนเรยกตวเองใหอาจารยหนอย
สมมตวาเรยกใชดงน
cout<<FindMoney(1000, 4, 4 );
ผลการท างานเปนอยางไร