4.1 (Summation) - sci.feu.ac.thsci.feu.ac.th/faa/dsa/bookPDFs/chap4-Recursion.pdf · Sum from 1 –...
Transcript of 4.1 (Summation) - sci.feu.ac.thsci.feu.ac.th/faa/dsa/bookPDFs/chap4-Recursion.pdf · Sum from 1 –...
Recursion เปนการเขยนโปรแกรมวธหนงทยอมให method เรยกตวเองในการประมวลผล มนอาจเปนเรองประหลาดส าหรบหลาย ๆ คนทเรมเขยนโปรแกรม แต recursion เปนวธทสามารถน ามาใชในการแกปญหาของการเขยนโปรแกรมใหดย งข น ในบทนเราจะมาท าความรจกกบ Recursion หลงจากจบบทเรยนนแลว ผอานจะไดทราบถง
o เทคนค และวธการมองการท างานในรปแบบของ Recursion o ตวอยางปญหาทางคณตศาสตร ทใช Recursion เปนเครองมอในการแกปญหา o ตวอยางการท างานของปญหาตาง ๆ ทใช Recursion เปนเครองมอ 4.1 การหาผลรวม (Summation) สมมตวาเราตองการหาคาของผลรวมของเลขตงแต 1 ถง 100 วธการทงายทสดในดานการเขยนโปรแกรมกคอ การน าเอา loop เขามาชวยในการหาผลรวมน ซงเราไดเคยท ามาแลวไมมากกนอย และมวธการเขยนทหลากหลาย หนงในนนกอาจเขยนไดดงน int sum = 0;
for(int i = 100; i > 0; i--)
sum += i;
ถาเราสงเกตใหด เราจะเหนวาการท างานของ loop มขนตอนในการหาผลรวมในรปแบบของ 100 + 99 + 98 + 97 + … + 1 และถาเราตองการหาคาของผลรวมใด ๆ ตงแต 1 ถง n เรากอาจเขยนขนตอนของการหาผลรวมนนไดในรปแบบของสมการทางคณตศาสตร ดงน n + (n – 1) + (n – 2) + (n – 3) + … + 1 จากการค านวณทเหนเรารวา ในการหาคาของ n ทอยทางดานซายนนจะตองอาศยคาของ n ทอยทางดานขวา และ n ทอยทางดานขวาสดเทานนทมคา (1) ทเราจะน าไปประมวลผลได ซงรปแบบของการประมวลแบบนสามารถทจะเขยนใหอยในรปแบบของ Mathematical induction1
ไดดงน sum(n) = 1 if n = 1 sum(n) = n + sum(n – 1) if n > 1 ในการออกแบบ method ทอยในรปแบบของ Recursion นน ส งทส าคญทสดในการออกแบบกคอ เงอนไขของการจบการท างานของ method ในการเรยกตวเอง ภาพท 4.1 แสดงถงเงอนไขท sum() หยดเรยกตวเอง เมอ n มคาเทากบ 1 เราเรมตนดวยการหาคาของ sum ท n = 5 ซงกยงไมไดผลลพธใด ๆ เพราะวาจากเงอนไขทก าหนด sum(5) = 5 + sum(4) ดงนนเราจงจ าเปนทจะตองหาตอไปเรอย ๆ จนกวาจะเจอ
1 วธการพสจนทฤษฎทางคณตศาสตรแบบหนงทใชตวเลขเปนตวชวยในการพสจน (whole numbers และ zero)
Recursion บทท 4
102
เงอนไขทท าใหเราไดคา เราจะไดคากตอเมอ n มคาเทากบ 1 ซงท าให sum() หยดเรยกตวเอง และ sum() กจะประมวลผลดวยคา 1 ทไดกบคาของ n ขณะนนซงกคอ 2 ท าใหเราไดคาใหมทเกดข นคอ 3 การประมวลผลจะเปนไปในลกษณะน (เราเรยกการประมวลผลแบบนวา Bubble-up Evaluation) จนกระทงในทสดเรากจะมาถงประโยคทเราเรมตนประมวลในครงแรก คอ sum(5) = 5 + sum(4) ซงเราสามารถหาคาไดเพราะเรารวาคาของ sum(4) คอ 10 ดงนนเราจงไดคาของ sum(5) เปน 15
ภาพท 4.1 การหาคาของ sum(5)
ถาเราจะถายทอดความคดของเราในการสราง method sum() ใหอยในรปแบบของ code ทใช Recursion เรากจะได code ดงน //calculate sum using recursion
public static int sum(int n) {
//base case; stop calling itself and bubble-up
if(n == 1)
return n;
else
return n + sum(n - 1);
}
ผอานควรสงเกตถงเงอนไขของการยตการเรยกตวเองของ sum() วาเปนไปตามทเราไดก าหนดไวในการออกแบบตงแตตน (เรามกเรยกเงอนไขนวา base case) หลงจากทเราเขยนโปรแกรมทดสอบน
สงคา 4 + 6 กลบออกไป
สงคา 3 + 3 กลบ
ออกไป
สงคา 2 + 1 กลบออกไป
สงคา 1 กลบออกไป
หาคาของ sum(5)
sum(4) 5 +
+ 4 sum(3)
3 + sum(2)
2 + sum(1)
1
สงคา 5 + 10 กลบออกไป 15
บทท 4 Recursion
103
1: /**
2: Finding summation of a given series
3: */
4:
5: class SumRecursion {
6: public static void main(String[] args) {
7: System.out.println("Sum from 1 - 5 is " + sum(5));
8: }
9:
10: //calculate sum using recursion
11: public static int sum(int n) {
12: //base case
13: if(n == 1)
14: return n;
15: else
16: return n + sum(n - 1);
17: }
18: }
ผลลพธทไดคอ Sum from 1 – 100 is 5050
4.1.1 เกดอะไรขนเมอ method เรยกตวเอง
เพอใหเหนการท างานของ Recursion เราอาจเปลยนแปลง code ดวยการน าเอาประโยคทแสดงผลของขนตอน และขอมลในขณะท sum() ถกเรยกในชวงเวลาตาง ๆ กนมาใชดงตวอยางทเหนน //calculate sum using recursion
public static int sum(int n) {
//base case
space(step++);
System.out.println("Calling sum(" + n + ")");
if(n == 1) {
space(--step);
System.out.println("Returned from sum(" + n + "), result = " + n);
return n;
}
else {
int temp = n + sum(n - 1);
space(--step);
System.out.println("Returned from sum(" + n + "), result = " + temp);
return temp;
}
}
//helper method to print spaces
public static void space(int n) {
for(int i = 0; i < n; i++)
System.out.print(" ");
}
ผลลพธทไดจากการ run ดวยคา n = 5 คอ Calling sum(5)
Calling sum(4)
Calling sum(3)
Calling sum(2)
Calling sum(1)
Returned from sum(1), result = 1
Returned from sum(2), result = 3
Returned from sum(3), result = 6
Returned from sum(4), result = 10
Returned from sum(5), result = 15
Sum from 1 - 5 is 15
Recursion บทท 4
104
จากผลลพธทไดเราจะเหนถงการเรยกตวเองของ sum() ดวยคาทลดลงทละหนง จนกระทงถงกรณสดทายทคาทสงเขาไปเปนหนง การบวกเลขจงเกดข นตามล าดบจนในทสดกยตเมอผลลพธของการบวกครงสดทายถกสงกลบออกไปยง main() 4.1.2 ข นตอนส าคญส าหรบการออกแบบโปรแกรมทใช Recursion ขนตอนทจ าเปนส าหรบ Recursion คอ
o Base case: เปนสวนส าคญของการเขยนโปรแกรมดวย recursion เพราะฉะนนเราตองมชดค าสงอยางนอย 1 ชดทเปน base case เชน เมอ n == 1 ใน method sum()
o การเรยกใช method ทกครงจะตองน าไปส base case ไมเชนนนกจะท าใหเกดการเรยกตวเองโดยไมหยด
4.2 Factorial เพอใหเรามความเขาใจใน Recursion มากยงข นเรามาลองดตวอยางของ Recursion แบบงาย ๆ อกตวหนง นนกคอการค านวณหาคาของผลคณของเลขทกตวใน range ทก าหนดให หรอทเรยกวา Factorial ซงมสตรทางคณตศาสตร คอ factorial(n) = 1 if n = 0
factorial(n) = n x (n – 1) x (n – 2) x … x 3 x 2 x 1 if n > 0
จากสมการของ Factorial เราสามารถทจะหาคาของ factorial(4) ได ซงกคอ factorial(4) = 4 x 3 x 2 x 1 = 24
ถาเราเขยน code เพอค านวณหาคาของ Factorial น เรากเขยนขนงาย ๆ ดวยการใช loop เชน
int n = 5, product = 1;
for(int i = n; i > 0; i--)
product *= i;
การหา Factorial ดวยการใช loop ทเหนดานบนกคลาย ๆ กบการหาผลรวมทเราไดท ามากอนหนาน ถาเราท าการหาคาของ Factorial ของ 4 ดวยมอ เรากจะได factorial(4) = 4 * factorial(3)
= 4 * (3 * factorial(2))
= 4 * (3 * (2 * factorial(1)))
= 4 * (3 * (2 * (1 * factorial(0))))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * (3 * 2)
= 4 * 6
= 24
ลองมาดโปรแกรมตวอยางการหา Factorial
1: /**
2: Finding factorial
3: */
4:
5: class Factorial {
6: public static void main(String[] args) {
7: int n = 5;
8:
9: System.out.println("factorial(" + n + ") = " + factorial(n));
10: }
11:
12: //finding factorial
13: public static int factorial(int n) {
14: if(n == 1)
15: return 1;
16: else
17: return n * factorial(n - 1);
18: }
บทท 4 Recursion
105
19: }
ผลลพธทไดคอ factorial(5) = 120
Factorial เปนเลขทเพมจ านวนอยางรวดเรวตามคาของตวเลขทสงเขาไป ผอานควรทดลอง run โปรแกรม Factorial ดวยคาทมขนาดใหญ ๆ เพอใหเหนถงการเพมข นของตวเลขทรวดเรว (อาจตองเปลยนชนดของขอมลจาก int ใหเปน long เพอรองรบผลลพธทมขนาดใหญข น) 4.3 การหาคาของเลขยกก าลง การหาคาของเลขยกก าลงใด ๆ เชน mn นนเราสามารถทจะน า Recursion มาชวยได แตกอนอน
เราตองหา base case ของการหาคาของเลขยกก าลงเสยกอน ซงถาสงเกตใหด เลขยกก าลงก คอ การเอาเลขนน ๆ มาคณกนตามจ านวนของก าลงทก าหนดไว ดงสมการทเหนน Mn = M x M(n – 1) if n > 0 Mn = 1 if n = 0 ตวอยาง เชน
55 = 5 x 54 54 = 5 x 53 53 = 5 x 52 52 = 5 x 51 51 = 5 x 50 50 = 1
ถาเราก าหนดให power(m, n) เปน method ทใชในการหาคาของ mn ถา m = 5 และ n = 5 เรากจะได power(5, 5) เปน power(5,5) = 5 * power(5,4)
= 5 * (5 * power(5,3))
= 5 * (5 * (5 * power(5,2)))
= 5 * (5 * (5 * (5 * power(5,1))))
= 5 * (5 * (5 * (5 * (5 * power(5,0)))))
= 5 * (5 * (5 * (5 * (5 * 1))))
= 5 * (5 * (5 * (5 * 5)))
= 5 * (5 * (5 * 25))
= 5 * (5 * 125)
= 5 * 625
= 3125
และเมอเปลยนใหเปน code ใน Java แลว เรากจะได //finding m to the power of n
public static int power(int m, int n) {
//base case
if(n == 0)
return 1;
else
return m * power(m, n - 1);
}
power(m, n) เปน method ทม parameter สองตว ตวทหนงเปนเลขทตองการยกก าลง สวนตวทสองเปนก าลงของเลขตวแรก ในการเรยกตวเองของ power() นน เราจะลดคาของ n ลงทละหนงสวนคาของ m เราจะทงไวเหมอนเดม โปรแกรม Power.java เปนโปรแกรมทเราเขยนขนมาทดสอบการท างานของ power() ทงนเราไดเปลยนแปลง code บางสวนเพอแสดงขนตอนการท างานของ power() ในชวงตาง ๆ เหมอนทเราท ากบ sum() กอนหนาน
1: /**
2: Calculating M to the power of n
3: */
Recursion บทท 4
106
4:
5: class Power {
6: static int step = 0;
7: public static void main(String[] args) {
8: int m = 5, n = 5;
9:
10: System.out.println("\nPower(" + m + ", " + n +") = " + power(m, n));
11: }
12:
13: //finding m to the power of n
14: public static int power(int m, int n) {
15: //base case
16: space(step++);
17: System.out.println("power(" + m + "," + n + ")");
18: if(n == 0) {
19: space(--step);
20: System.out.println("power(" + m + "," + n + ") = " + 1);
21: return 1;
22: }
23: else {
24: int temp = m * power(m, n - 1);
25: space(--step);
26: System.out.println("power(" + m + "," + n + ") = " + temp);
27: return temp;
28: }
29: }
30:
31: //helper method to print spaces
32: public static void space(int n) {
33: for(int i = 0; i < n; i++)
34: System.out.print(" ");
35: }
36:
37: }
ผลลพธทเราไดจากการ run โปรแกรมคอ power(5,5)
power(5,4)
power(5,3)
power(5,2)
power(5,1)
power(5,0)
power(5,0) = 1
power(5,1) = 5
power(5,2) = 25
power(5,3) = 125
power(5,4) = 625
power(5,5) = 3125
Power(5, 5) = 3125
4.4 Fibonacci Numbers Fibonacci numbers เปนกลมของตวเลขทเกดข นจากการเอาตวเลขกอนหนานนสองตวมารวมกนเปนตวเลขทอยถดไปใน ต าแหนงทสาม เชน 0 1 1 2 3 5 8 13 21 34 … จาก pattern ทมอยใน Fibonacci numbers เราสามารถทจะเขยน method เพอท าการหา Fibonacci numbers ดวยเทคนคของการใช recursion ดง algorithm ทเหนน (ไมใช algorithm ทดของการใช recursion – fib(number – 2) จะไปเรยก fib(number – 1) ซงมการเรยกตางหากแลว ท าใหเกดการซ าซอนของการท างานโดยไมจ าเปน)
บทท 4 Recursion
107
Algorithm fib(number)
if(number is 0 OR number is 1)
return number
else
return fib(number – 1) + fib(number – 2)
โปรแกรม Fib.java ส าหรบการหา Fibonacci numbers จาก Algorithm ทให
1: /**
2: Finding Fibonacci numbers
3: */
4:
5: class Fib {
6: public static void main(String[] args) {
7: int number = 30;
8:
9: for(int i = 0; i <= number; i++) {
10: if(i % 7 == 0)
11: System.out.println();
12: System.out.printf("%8d", fib(i));
13: }
14: System.out.println();
15: }
16:
17: //findin Fibonacci numbers
18: public static int fib(int num) {
19: //base case
20: if(num == 0 || num == 1)
21: return num;
22: else
23: return fib(num - 1) + fib(num - 2);
24: }
25: }
ผลลพธของการ run
0 1 1 2 3 5 8
13 21 34 55 89 144 233
377 610 987 1597 2584 4181 6765
10946 17711 28657 46368 75025 121393 196418
317811 514229 832040
ผอานควรทดลอง run โปรแกรมดวยคาของ number ทแตกตางกนเพอใหเหนถงเวลาทโปรแกรมใช ในการค านวณวาแตกตางกน มากนอยอยางไร 4.5 การกลบตวอกษร (reverse) ใน string ดวยการใช recursion โปรแกรมตวอยางตอไปนเปนโปรแกรมตวอยาง ทเปลยน string ทผใชสงเขามาใหอยในรปแบบของการกลบหว กลบหาง (reverse)
1: /**
2: Reverse a string with recursion
3: */
4:
5: import java.io.*;
6:
7: class ReverseString {
8: public static void main(String[] args) {
9: String str = "";
10: BufferedReader reader;
11: InputStreamReader in;
12:
13: //getting input from keyboard
14: in = new InputStreamReader(System.in);
15: reader = new BufferedReader(in);
16: try {
17: System.out.print("Enter a string: ");
18: str = reader.readLine();
19: }
20: catch(IOException err) {
Recursion บทท 4
108
21: System.err.println("I/O error!");
22: System.exit(1);
23: }
24: //calling reverse() to reverse a string
25: reverse(str);
26: }
27:
28: //reversing a string
29: public static void reverse(String s) {
30: reverse(s, s.length()-1);
31: }
32:
33: //main method to print String in reverse order
34: public static void reverse(String s, int n) {
35: //base case
36: if(n < 0)
37: return ;
38: else {
39: //print character at n
40: System.out.print(s.charAt(n));
41: reverse(s, n - 1);
42: }
43: }
44: }
เราใชความยาวของ string เปนตวก าหนดการยตการท างานของ method reverse() ดวยเหตนเราจงตองใช helper method เปนตวท างานใหเรา เราเรยก method reverse(s, n) ครงแรกดวยความยาวของ string ลบ 1 ทงนกเนองจากวาเราตองการทจะ print ตวอกษรทต าแหนงสดทายของ string เราใช method charAt() เปนตวดงเอาคาของตวอกษรจากต าแหนงทก าหนดไว (n) หลงจากนนเรากเรยก reverse() ใหมดวยคาของ n – 1 และในทสดคาของ n กจะมคานอยกวา 0 (คาทเปนจรงคอ -1) ซงคา -1 นแหละทเปนตวก าหนดการหยดการท างานของ reverse() ผลลพธทไดจากการ run โปรแกรม Enter a string: I am in Chiang Mai
iaM gnaihC ni ma I
จะเหนวาการท าให string กลบหว กลบหางของเรานนเปนการกลบแบบตรง ๆ ซงท าใหเราไมสามารถทจะอานขอความได ตวอยางตอไปนเปนการกลบ string ทยงรกษาความเปนค านน ๆ ไว 4.5.1 การ reverse string ทรกษารปแบบของค าไว
1: /**
2: Reverse a string which preserve readability of words
3: */
4:
5: import java.io.*;
6:
7: class StringReversed {
8: public static void main(String[] args) {
9: String str = "";
10: BufferedReader reader;
11: InputStreamReader in;
12:
13: //getting input from keyboard
14: in = new InputStreamReader(System.in);
15: reader = new BufferedReader(in);
16: try {
17: System.out.print("Enter a string: ");
18: str = reader.readLine();
19: }
20: catch(IOException err) {
21: System.err.println("I/O error!");
22: System.exit(1);
23: }
24:
25: //calling reverse() to reverse a string
26: System.out.println("String reversed: " + reverse(str));
บทท 4 Recursion
109
27: }
28:
29: /**
30: routine to reverse a string by
31: 1. call flip() to reverse all characters
32: 2. find each word and call flip() to reverse it back
33: 3. replace the old word with the new one just flipped
34: 4. return a new string
35: */
36: private static String reverse(String string) {
37: String SPACE = " ";
38: //reverse a given string
39: StringBuffer s = new StringBuffer(flip(string));
40: int i = s.indexOf(SPACE);
41: int j = 0;
42: String oldWord = null, newWord = null;
43: //find each word and reverse it, then replace
44: //the old word with the new one
45: while(i >= 0) {
46: oldWord = s.substring(j, i);
47: newWord = flip(oldWord);
48: s.replace(j, i, newWord);
49: for(j = i+1; s.charAt(j) == ' '; j++) {}
50: i = s.indexOf(SPACE, j);
51: }
52: //take care of last word
53: oldWord = s.substring(j);
54: newWord = flip(oldWord);
55: s.replace(j, s.length(), newWord);
56:
57: return s.toString();
58: }
59:
60: //flip all characters in a string
61: private static String flip(String s) {
62: //base case
63: if(s.length() < 2)
64: return s;
65: else
66: return flip(s.substring(1)) + s.charAt(0);
67: }
68: }
ผลลพธทไดจากการ run คอ Enter a string: I love Chiang Mai
String reversed: Mai Chiang love I
4.6 Binary search กบ Recursion Binary search ทเราไดพดถงในบทท 1 ใช loop เปนตวจดการกบขอมล ถาเราจะน าเอา Recursion เขามาใชเราตองยกเลกการใช loop มาด Binary search ทเราไดเขยนขนกอนหนาน public boolean binarySearch(Comparable key) {
int lower = 0;
int upper = elems - 1;
int mid;
while(true) {
mid = (lower + upper) / 2;
if(arr[mid].equals(key))
return true; //found it
else if(lower > upper)
return false; //not found
else {
//divide array into halves
if((arr[mid].compareTo(key)) < 0)
lower = mid + 1; //in upper half
else
upper = mid - 1; //in lower half
}
Recursion บทท 4
110
}
}
binarySearch() ทเหนดานบนน เปลยนการคนหาในสวนตาง ๆ ดวยการค านวณหา lower และ upper ทกครงใน loop จนกวาจะท างานเสรจ เพราะฉะนนถาจะเปลยนมาใช Recursion เราตองสงคาของ lower และ upper ทหาไดไปให method ทท าการคนหาขอมลให เราเขยน method 2 ตวคอ search() และ recBinSearch() โดยผใชจะเรยกใช search() ในการคนหา สวน recBinSearch() เปน method ภายในทเปนกลไกหลกของการคนหาดวยการใช Recursion เขามาชวย public boolean search(Comparable key) {
return recBinSearch(key, 0, elems - 1);
}
ภายใน search() เราเรยก recBinSearch() ดวย parameter 3 ตวคอ
o key ทตองการคนหา o index เรมตน (lower) ของ array o index สดทาย (upper) ของ array
และ code ของการคนหาดวย Binary Search แบบทใช recursion มดงน //recursive Binary search
private boolean recBinSearch(Comparable k,
int lower, int upper) {
int mid;
mid = (lower + upper) / 2;
if(arr[mid].equals(k))
return true;
else if(lower > upper)
return false;
else {
//search on the right half
if((arr[mid].compareTo(k)) < 0)
return recBinSearch(k, mid + 1, upper);
//search on the left half
else
return recBinSearch(k, lower, mid - 1);
}
}
การท างานหลก ๆ ของการคนหาเกดภายใน method recBinSearch() ซงมการเปลยนแปลงเพยงแค การเพม parameter ใหสองตว พรอมทงเปลยนการค านวณหา lower และ upper ให เปนการเรยกใช recBinSearch() แทนพรอมทงการเลกใช loop ผอานควรเขยนโปรแกรมทดสอบเพอท าความเขาใจกบการคนหาดวย recBinSearch() ใหดย งข น
สรป Recursion เปนวธการทสามารถน ามาใชในการเขยนโปรแกรมวธการหนง โดยทวไปการใช recursion มกจะมคา overhead สงกวาการใช loop เขามาชวยในการเขยน เพราะฉะนน ถาหลกเลยงการใช recursion ไดกควรทจะหลกเลยง แตถาจ าเปนและการใช recursion ท าให code ดงายขน บางครงเรากควรทจะใช recursion ทงนและทงนนกข นอยกบการออกแบบ recursion และ ลกษณะของปญหาทมอย เชนการใช recursion ในภาษา lisp และ prolog ซง
เปนภาษาทมการใช recursion อยางมาก และจะใช recursion ในการค านวณและประมวลอยางสม าเสมอ โดยสรปแลวเราไดพดถง การแกปญหาดวย Recursion การหาเงอนไขในการยตการเรยกตวเองของ method การประมวลผลของ method วามขนตอนอยางไร ตวอยางการเขยนโปรแกรมดวยการใช Recursion
บทท 4 Recursion
111
แบบฝกหด 1. การหา square root ของเลขใด ๆ นนมวธการหลายแบบ มวธการแบบหนงเรยกวา วธการ
ของ Newton ซงมการค านวณ หาดงน
Algorithm squareRoot(num, ans, tol)
If(|ans2 – num| <= tol)
squareRoot(num, ans, tol) = ans
else
squareRoot(num, (ans2 + num) / (2 x ans), tol)
จงเขยน recursive method เพอหา square root ของตวเลขใด ๆ ทปอนเขามาจาก keyboard ทดสอบดวยการเรยก squareRoot(5, 2, 0.01) และ squareRoot(4, 2, 0.01)
2. การหาตวหารรวม (Greatest Common Divisor) ของ integer 2 ตว หาไดดวยวธการของ
Euclid ดงน
gcd(x, y) = gcd(y, x) if x < y gcd(x, y) = x if y = 0; gcd9x, y) = gcd(y, x mod y) ถาไมอยใน 2 case แรก จงเขยน recursive method เพอหา gcd ของ integer ทปอนเขามาจาก keyboard
3. จงเขยน recursive method ทค านวณหาความยาวของ linked-list
4. จงเขยน recursive method ทค านวณหาผลรวม n ครงของ series
1 +1/2 + 1/3 +1/4 + 1/5 + … + 1/n 5. Palindrome เปน string ทอานแลวไดความหมายเหมอนกนทง จากทางดานหนา และทาง
ดานหลง เชน
Anna Go dog Madam, I’m Adam จงเขยน recursive method ทตรวจสอบวา string ทก าหนดใหเปน palindrome หรอไม
6. Perfect number คอตวเลขทเปนผลรวมของ factor ของมนเองเชน 6 = 1 + 2 + 3 จง
เขยน recursive method ทค านวณหา perfect number ทม factor นอยกวาตวมนเอง (1 < 6, 2 < 6, 3 < 6 etc.)
7. จงเขยน recursive method ท convert string ของตวเลขใหเปน integer เชน string “12345” จะถกเปลยนใหเปน 12345
8. จงเขยน recursive method ทค านวณหาจ านวนครงของ character ทปรากฏอยใน string
ทก าหนดให 9. จงเขยน recursive method ทเปลยนเลขฐานสบใหเปนเลขฐานสอง 10. จงอธบายถงการท างาน และหาผลลพธของโปรแกรมทใหน
class WhereAmI {
public static void main(String[] args) {
String[] str = {"Am ", "in ", "main()"};
System.out.println(str[0] + str[1] + str[2]);
Recursion บทท 4
112
main(str);
}
}
11. จงเขยน method ทหาคาของ function ทใหน พรอมทงเขยนโปรแกรมทดสอบ
f(n) = 0 if n = 0 f(n) = f(½ n) if n = เลขค และ n > 0 f(n) = 1 + f(n – 1) if n = เลขค และ n > 0
12. จงเขยน recursive method ทท าการหาจ านวนของ 1 ทอยในเลขฐานสอง เชนสมมตวา
เลขฐานสองทวามคาเปน 5 = 1012 ดงนน จ านวนของ 1 คอ 2 ตว
หมายเหต: จ านวนของ 1 ในเลขฐานสองใด ๆ (n) เทากบจ านวนของ 1 ทอยใน n/2 บวกอกหนงถาเลขตวนนเปนเลขค
13. จงเขยนโปรแกรมทท าการหา permutation ของ String ก าหนดใหดวยการใช Recursion
เชน ถา String มคาเปน "abc" เราจะไดคาทงหมดคอ abc, acb, bac, bca, cab, cba 14. Binomial coefficients C(N, k) สามารถเขยนใหอยรปแบบของ Recursion ไดดงน
C(N, 0) = 1, C(N, N) = 1, C(N, k) = C(N – 1, k) + C(N – 1, k – 1) ถา 0 < k < N จงหาผลลพธของ Binomial coefficients ดงกลาวดวยการใช Recursion
15. จงเขยนโปรแกรมทหาคาสงสดทมอยใน array ดวยการใช Recursion
แนะน า: ควรใชแนวทางของ binary search ทใช recursion int max(int[] array, int left, int right);
โดยทตวแปร left และ right เปนจดเรมตนและจดสดทายของขอมลทอยใน array
ตามล าดบ