You are on page 1of 4

Data Structure and Algorithm Laboratory: lab #4 Recursion . !

" #$%$&'%() 1/4

ชื่อ-นามสกุล รหัส หอง


หมายเหตุ: นําหนังสือและเอกสารทีใ่ ชในการสอนทัง้ หมดเขาหองทดลองทุกครัง้ ทีท่ าํ การทดลอง
ภาควิชาวิศวกรรมคอมพิวเตอร คณะวิศวกรรมศาสตร
สถาบันเทคโนโลยีพระจอมเกลาเจาคุณทหารลาดกระบัง
01072118 วิชา Data Structure and Algorithm Laboratory
การทดลอง
การทดลอง Recursion วัตถุประสงค ศึกษาเรือ่ ง Recursion
การทดลองที่ 1 เขียน recursive ฟงกชั่นรีเทอรน int mult(int a, int b); ผลคูณของเลขจํานวนนับ
การทดลองที่ 2 โปรแกรมขางลางใหคาตั้งตนและพิมพอะเรย โดยใหเขียนฟงกชั่นเปนเทมเพลทของไทป T ใดๆ
หากคิดไมออก ศึกษาเฉลยขางหลัง เขียนฟงกชั่น แลวรันดู หากทําเทมเพลทไมเปนใหเอาบรรทัด
//template ออก และเปลี่ยน type T* ของพารามิเตอร a ที่หัวฟงกชั่นเปน int*

1. ศึกษารีเคอซีฟฟงกชั่น initArr และ run step สังเกตุดูตอน call recursion และหยุด call recursion
template<class T> //template int main() {
void initArr(T* a, int v, int i, int lastIndex){ const int MAX = 3;
//init a ดวยคา v ตัง้ แตอน
ิ เด็กซ i ถึง lastInd int a[MAX];
if (i <= lastIndex){ initArr(a, 5, 0, MAX-1);
a[i] = v; initArr(a, 3, 0, MAX-1);
initArr(a, v, i+1, lastIndex); // recursion
} }
}

2. เขียนรีเคอซีฟฟงกชั่น void initArrWithInd(T* a, int i, int lastIndex) เพื่อ init อะเรย a ดวยเลขอินเด็กซ คือ
a[0] = 0, a[1] = 1, … , a[lastIndex] = lastIndex
3. เขียนรีเคอซีฟฟงกชั่น void print(T* a, int i, int lastIndex) เพื่อพิมพอะเรย a ตั้งแตอินเด็กซ i ถึง lastIndex
4. เขียนรีเคอซีฟฟงกชั่น revPrint เพื่อพิมพอะเรย a ตั้งแตอินเด็กซ lastIndex ถึง i (คิดพารามิเตอรเอง)
การทดลองที่ 3 โปรแกรมขางลางใหคาตั้งตนและพิมพลิงคลิสต โดยใหเขียนฟงกชั่นเปนเทมเพลทของไทป T ใดๆ
หากคิดไมออก ศึกษาเฉลยขางหลัง เขียนฟงกชั่น แลวรันดู
1. เขียนรีเคอซีฟฟงกชั่น print เพื่อพิมพลิสตจากหัวไปทาย และ revPrint เพื่อพิมพลิสตจากทายมาหัว
int main() { /*
node<int> *h, *p, *t; h = t = NULL;
createListWithNodeNo(h, t, 1, 5);
h = t = new node<int>(1); */
for(int i=2; i<=4; i++){//creat list cout << endl; cout << "print: ";
p = new node<int>(i); print(h);
t->next = p; cout << "\nrevPrint: ";
t = p; revPrint(h);
} return 0;
}
2. คอมเมนตบรรทัดที่ไฮไลท และเอาคอมเมนต /* */ ออก เขียนรีเคอซีฟฟงกชั่น createListWithNodeNo
เพื่อสรางลิสตใหเหมือนบรรทัดที่คอมเมนตออกไป (คิดพารามิเตอรเอง)

,-. $/- $# %%0.01$ 2%) 345.


Data Structure and Algorithm Laboratory: lab #4 Recursion . !" #$%$&'%() 2/4
การทดลองที่ 4 เขียน recursive โปรแกรม สําหรับ knapsack (แนปเสค) problem ขางลาง outputs:
outputs
มีเงิน k บาท มีของ n ชิ้นราคา b1, b2, ..., bn จะซึ้อของใหเงินหมดพอดี (ไมเหลือและไมขาด) ไดหรือไม 20
10 5 5
ถาได ไดราคาเทาใดบาง (หาทุกคาที่ซื้อได) นัน้ คือ B = { b1, b2, ..., bn } เปน set ของ integers ที่มี 10 5 3 2
10 5 3 2
คาซ้าํ ได มี subset ของ B หรือไมที่ sum ของสมาชิ
ของสมาชิกทัง้ หมด = k พอดี ของราคาเทากันถือเปนคนละ 10 10
อันกัน ดังนั้น k = 20, B = {20, 10, 5, 5, 3, 2, 20, 10} outputs จะได 9 แบบ ดังแสดง 5 5 10
5 3 2 10
5 3 2 10
ตอบคําถามตอไปนี้กอนทํา 20
1. จะใช data structure อะไรเก็บ 1. ของ(ราคา)ทั้งหมดในตลาด 2. ของ(ราคา)ใน sack
2. recursive part คืออะไร ==> โจทยคืออะไร อะไรที่ทําซ้ําๆ กัน เพียงเปลี่ยนพารามิเตอรไป
3. simple part (base part) คืออะไร ==> เราจะหยุดซื้อของเมื่อไรบาง ?
ตัวอยางโปรแกรม การทดลองที่ 2 รีเคอซีฟให
ฟใหคา ตัง้ ตนและพิมพอะเรย
#include <iostream>
using std::endl; using std::cout; using std::cin;
template<class T>
void initArr(T* a, int v, int i, int lastIndex){
//init array a with v from index i to index lastIndex

if (i <= lastIndex){
a[i] = v;
initArr(a, v, i+1, lastIndex);//call recursion
}
}
template<class T>
void initArrWithInd(T* a, int i, int lastIndex){
//init array a with index number from index i to index lastIndex

if (i <= lastIndex){
a[i] = i;
initArrWithInd(a, i+1, lastIndex);//call recursion
}
}
template<class T>
void print(T* a, int i, int lastIndex){
//print a from index 0 to index MAX-1

if (i <= lastIndex){
cout << a[i] << ' ';
print(a, i+1, lastIndex);//call recursion
}
}
template<class T>
void revPrint(T* a, int i, int lastIndex){
//reverse print a from index MAX-1 to index 0

if (i <= lastIndex){
revPrint(a, i+1, lastIndex);//call recursion
cout << a[i] << ' ';
}
}
int main() {
const int MAX = 3;
int a[MAX];

initArr(a, 5, 0, MAX-1);//init a with 5 from index 0 to index MAX-1


cout << endl; cout << "print: "; print(a, 0, MAX-1);

initArr(a, 3, 0, MAX-1);//init a with 3 from index 0 to index MAX-1


cout << "\n\nprint: "; print(a, 0, MAX-1);

initArrWithInd(a, 0, MAX-1);//init a with index from index 0 to index MAX-1


cout << "\n\nprint: "; print(a, 0, MAX-1);
cout << "\nrevPrint: "; revPrint(a, 0, MAX-1);
return 0;
}

,-. $/- $# %%0.01$ 2%) 345.


Data Structure and Algorithm Laboratory: lab #4 Recursion . !" #$%$&'%() 3/4
ตัวอยางโปรแกรม การทดลองที่ 3 รีเคอซึฟใหคา ตัง้ ตนและพิมพอะเรย
#include <iostream>
using std::endl; using std::cout; using std::cin;

//------Recursive createListWithNodeNo, print, reverse print linked list


template<class T>
struct node{
T data;
node<T>* next;
node(const T& d = T(), node<T>* nx = NULL):data(d), next(nx){}
};
template<class T>
void print(node<T> * p){
//print from p to last node

if (p){
cout << p->data;
print(p->next);//call recursion
}
}
template<class T>
void revPrint(node<T> * p){
//reverse print from last node to p

if (p){
revPrint(p->next);//call recursion
cout << p->data;
}
}
template<class T>
void createListWithNodeNo(node<T> *& h, node<T> *& t, int i, int size){
node<T> *p;

if (h == NULL) {
h = t = new node<int>(i);
createListWithNodeNo(h, t, i+1, size); //call recursion
}
else if (i < size){
p = new node<int>(i);
t->next = p;
t = p;
createListWithNodeNo(h, t, i+1, size); //call recursion
}
}
int main() {
node<int> *h, *p, *t;

h = t = new node<int>(1);
for(int i=2; i<=4; i++){ //creating list
p = new node<int>(i);
t->next = p;
t = p;
}//now h & t points to head and tail of a list
/*
h = t = NULL;
createListWithNodeNo(h, t, 1, 5);
*/
cout << endl; cout << "print: "; print(h);
cout << "\nrevPrint: "; revPrint(h);
return 0;
}

,-. $/- $# %%0.01$ 2%) 345.


Data Structure and Algorithm Laboratory: lab #4 Recursion . !" #$%$&'%() 4/4

ตัวอยางโปรแกรม การทดลองที่ 4 แนปแสค knapsack


#include <iostream> //array version
using std::endl; using std::cout; using std::cin;
const int MAX = 20;
int numsol = 0;
int p[MAX]; //items(prices) in supermarket
int np; //#items in supermarket

void pick(int start, int m, int ns, int *sack){//ns=total items in a sack
for(int i=start; i<np; i++){//every combination of prices
sack[ns++] = p[i]; // pick to the sack
m -= p[i]; // pay
if (m == 0){ // got solution, use up money
numsol++;
for(int j=0; j<ns; j++) //print sack
cout<<sack[j]<<" ";
cout<<endl;
}else if (m>0 && i!=np) //still money & item left
pick(i+1,m,ns,sack);//go pick another item
ns--; //take item i out of the sack(for other solution)
m+=p[i];//return money for item i back
} //for
} //pick

void main(){
int sack[MAX]; //items(prices) in sack
int m, i; //m = money we got

cout << "\nEnter set of prices, end with 0 or Ctrl-Z then <Enter>: ";
np = 0;
while(cin>>i && i>0 && np<MAX)
p[np++] = i; //after the loop np = #items

cout << "How much you got? "; cin >> m; cout << endl;
pick(0,m,0,sack);//start pick 1st item at p[0], now 0 item in sack
if (!numsol) cout << "\nNo solution!\n";
}

ที่ไมสง p{MAX] และ np เปนพารามิเตอรของ pick เนื่องจากทั้งคูไมเปลี่ยนคา หากไมตองการใช global ใน


pick อาจทําใหทั้งคูเปน static ใน pick และ init ขางใน pick เฉพาะครั้งแรกที่เรียก pick คือเมื่อ start == 0

,-. $/- $# %%0.01$ 2%) 345.

You might also like