Click here to load reader

Rekursion - cse-lab.ethz.ch

  • View
    0

  • Download
    0

Embed Size (px)

Text of Rekursion - cse-lab.ethz.ch

Martin Maag November 30, 2010
Rekursion
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
http://www.cse-lab.ethz.ch
Swiss Federal Institute of Technology Zurich Politecnico federale di Zurigo Ecole polytechnique federale de Zurich´ ´
Informatik fur Mathematiker und Physiker Serie 8 HS10
http://www.ti.inf.ethz.ch/ew/courses/Info1 10/
A j i
string_matching.cpp m(n ! m + 1)
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
Swiss Federal Institute of Technology Zurich Politecnico federale di Zurigo Ecole polytechnique federale de Zurich´ ´
Informatik fur Mathematiker und Physiker Losung 8 HS10
http://www.ti.inf.ethz.ch/ew/courses/Info1 10/
Aufgabe 1
• Erweitere 2D Array um 1 zusätzliche Dimension • {oben, rechts, unten, links}
• 4 mögliche Ziele • Ziel mit jeder Ausrichtung erreicht
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
for (bool* r=present; r<present+n; ++r) *r = false;
// read number into the array and remember that it was read
for (int* p=a; p<a+n; ++p) { std::cin >> *p; if (*p >= 0 && *p < n)
present [*p] = true; }
// check whether we have read all numbers in {0,... ,n -1}
bool ok = true; for (bool* r=present; r<present+n; ++r)
}
if (ok) { // do the cycle decomposition . Here we reuse the array present
// and remove from it all numbers that we have already put into
// some cycle
std::cout << "cycle decomposition is "; int next = 0; // next number not yet put into a cycle
while (next < n) { // output cycle starting with next; we must come back to next
// below: assuming we would come back to some other element
// on the cycle , that element would have two preimages under
// pi , a contradiction
std::cout << next << " "; present[next] = false; next = a[next]; // next -> pi(next)
} while (next != first ); std::cout << ") ";
} // delete arrays
}
Solution to Exercise 85. s = a . . . ab m − 1 a b t = a . . . a n a m
b n − m + 1 {1, . . . ,m} {n − m + 1, . . . , n} m(n − m + 1)
Solution to Exercise 86.
Exercise 85 m > 1, n m s m t n
m(n−m+ 1)
int a[4][2][3] = { // the 4 elements of a:
{ // the 2 elements of a[0]:
{2, 4, 5}, // the three elements of a[0][0]
{4, 6, 7} // the three elements of a[0][1]
}, { // the 2 elements of a[1]:
{1, 5, 9}, // the three elements of a[1][0]
{4, 6, 1} // the three elements of a[1][1]
}, { // the 2 elements of a[2]:
{5, 9, 0}, // the three elements of a[2][0]
{1, 5, 3} // the three elements of a[2][1]
}, { // the 2 elements of a[3]:
} };
http://www.cse-lab.ethz.ch
• Lesbarkeit wichtiger als Kompaktheit
6
//Output; invA ausgeben std::cout<<"\n"<<"invA= \n"; for(int m=0;m<3;++m){ for(int n=0;n<3;++n){ std::cout <<invA[m][n]<<" "; if((n+1)%3==0)std::cout<<"\n"; } }
//Output; invA ausgeben std::cout << "\n" << "invA= \n"; for(int m = 0; m < 3; ++m){ ! for(int n = 0; n < 3; ++n){ ! ! std::cout << invA[m][n] << " "; ! ! if((n+1)%3 == 0) ! ! ! std::cout << "\n"; ! } }
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
• Beispiele: • Fakultät:
• Fibonacci Reihe: • f(0) = 0, f(1) = 1, f(n) = f(n-1) + f(n-2)
• Ackermannfunktion: A(m,n): • m = 0 -> n + 1
• m > 0, n = 0 -> A(m-1,1)
• m > 0, n > 0 -> A(m-1, A(m,n-1))
7
http://www.cse-lab.ethz.ch
Beispiele
8
// POST: return value is n! int fac(int n) { ! if n<=0 return 1; ! return n*fac(n-1); }
// POST: return value is the n-th Fibonacci number F_n unsigned int fib (unsigned int n) { if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); // n > 1 }
// POST: return value is the Ackermann function value A(m,n) unsigned int A (unsigned int m, unsigned int n) { if (m == 0) return n+1; if (n == 0) return A(m-1,1); unsigned int param = A(m, n-1); return A(m-1, param); }
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
Σ = {F,+,−} s = F + F + F + F P
F → FF + F + F + F + F + F − F.
Σ = {X, Y,+,−} s = Y P
X → Y + X + Y
Y → X − Y − X.
α = 60 X Y
Exercise 124 1, 2, 3
n
2 3 (2, 3) hanoi.cpp
n n = 2 (1, 2)(1, 3)(2, 3)
n = 3
http://www.cse-lab.ethz.ch
Informatik (D-MATH, D-PHYS)
Türme von Hanoi
• Verschiebe Turm mit n Scheiben von a nach b • 3 Positionen ∈ {1,2,3}
• Keine Scheibe darf auf eine kleinere Scheibe gestellt werden
• Idee für n Scheiben: • Verschiebe Turm mit n-1 Scheiben von a nach c
• a+b+c = 6, c=6-a-b
• Verschiebe Scheibe n von a nach b
• Verschiebe Turm mit n-1 Scheiben von c nach b
10
http://www.cse-lab.ethz.ch
Beispiele
11
// PRE: a and b are different and both in {1,2,3} // POST: the sequence of moves necessary to transfer a stack of n // disks from peg a to peg b is written to standard output void hanoi (const unsigned int n, const int a, const int b) { if (n > 0) { // move topmost n-1 disks from a to helper peg 6-a-b hanoi (n-1, a, 6-a-b); // move bottommost disk from a to b std::cout << "(" << a << "," << b << ")"; // move the n-1 disks from the helper peg to the b hanoi (n-1, 6-a-b, b); } }
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
Swiss Federal Institute of Technology Zurich Politecnico federale di Zurigo Ecole polytechnique federale de Zurich´ ´
Informatik fur Mathematiker und Physiker Serie 10 HS10
http://www.ti.inf.ethz.ch/ew/courses/Info1 10/
k + n!1
,
k
n!1
Skript-Aufgabe 116 (6 Punkte)
(20), (10, 10), (10, 5, 5), (5, 5, 5, 5)
4
partition.cpp
// PRE: [first , last) is a valid nonempty range that describes // a sequence of denominations d_1 > d_2 > ... > d_n > 0 // POST: return value is the number of ways to partition amount // using denominations from d_1 , ..., d_n unsigned int partitions (unsigned int amount ,
const unsigned int* first , const unsigned int* last);
Skript-Aufgabe 121 (5 Punkte)
x
// PRE: [first , last) is a valid range , and the elements *p, // p in [first , last) are in ascending order // POST: return value is a pointer p in [first , last) such // that *p = x, or the pointer last , if no such pointer // exists const int* binary_search (const int* first , const int* last , const int x) {
const int n = last - first; if (n == 0) return last; // empty range if (n == 1) {
if (*first == x) return first;
else return last;
} // n >= 2 const int* middle = first + n/2; if (* middle > x) {
// x can’t be in [middle , last) const int* p = binary_search (first , middle , x); if (p == middle)
return last; // x not found else
return p; } else
}
Abgabe:
http://www.cse-lab.ethz.ch
• Funktion arbeitet jeweils mit den obersten
• Nach Ende des Aufrufs werden Variabeln gelöscht
• Bsp: fac(3)
13
// POST: return value is n! int fac(int n) { ! if n<=0 return 1; ! return n*fac(n-1); }
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
• Rekursive Formulierungen sind: • einfacher zu schreiben
• aber weniger effizient • Funktionswerte mehrmals ausgewertet
• Call Stack
14
http://www.cse-lab.ethz.ch
15
// Prog: rec2it2.cpp // rewrites a recursive function in iterative form a la Fibonacci #include <iostream >
unsigned int f (const unsigned int n) {
if (n <= 2) return 1; return f(n-1) + 2 * f(n-3);
}
unsigned int f_it (const unsigned int n) {
if (n <= 2) return 1; unsigned int a = 1; // f(0) unsigned int b = 1; // f(1) unsigned int c = 1; // f(2) for (unsigned int i = 3; i < n; ++i) {
const unsigned int a_prev = a; // f(i -3) a = b; // f(i -2) b = c; // f(i -1) c = b + 2 * a_prev; // f(i)
} return c + 2 * a; // f(n -1) + 2 * f(n -3)
}
int main() {
std::cout << "Comparing f and f_it ...\n"; for (int n = 0; n < 100; ++n)
std::cout << f(n) << " = " << f_it(n) << "\n";
n/2
// Prog: rec2it2.cpp // rewrites a recursive function in iterative form by using an array #include <iostream >
unsigned int f (const unsigned int n) {
if (n == 0) return 1; return f(n-1) + 2 * f(n/2);
}
unsigned int f_it (const unsigned int n) {
if (n == 0) return 1; unsigned int* const f_values = new unsigned int[n+1]; // f(0) ,... ,f(n) f_values [0] = 1; for (unsigned int i=1; i<=n; ++i)
}
// Prog: rec2it2.cpp // rewrites a recursive function in iterative form a la Fibonacci #include <iostream >
unsigned int f (const unsigned int n) {
if (n <= 2) return 1; return f(n-1) + 2 * f(n-3);
}
unsigned int f_it (const unsigned int n) {
if (n <= 2) return 1; unsigned int a = 1; // f(0) unsigned int b = 1; // f(1) unsigned int c = 1; // f(2) for (unsigned int i = 3; i < n; ++i) {
const unsigned int a_prev = a; // f(i -3) a = b; // f(i -2) b = c; // f(i -1) c = b + 2 * a_prev; // f(i)
} return c + 2 * a; // f(n -1) + 2 * f(n -3)
}
int main() {
std::cout << "Comparing f and f_it ...\n"; for (int n = 0; n < 100; ++n)
std::cout << f(n) << " = " << f_it(n) << "\n";
n/2
// Prog: rec2it2.cpp // rewrites a recursive function in iterative form by using an array #include <iostream >
unsigned int f (const unsigned int n) {
if (n == 0) return 1; return f(n-1) + 2 * f(n/2);
}
unsigned int f_it (const unsigned int n) {
if (n == 0) return 1; unsigned int* const f_values = new unsigned int[n+1]; // f(0) ,... ,f(n) f_values [0] = 1; for (unsigned int i=1; i<=n; ++i)
}
http://www.cse-lab.ethz.ch
16
// POST: return value is n! int fac(int n) { ! if (n<=0) return 1; ! return n*fac(n-1); }
// POST: return value is n! int fac2(int n) { ! if (n==0) return 1; ! return n*fac2(n-1); }
Endlosschleife für negative Zahlen
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
http://www.cse-lab.ethz.ch
}


n + 1, m = 0 A(m − 1, 1), m > 0, n = 0 A(m − 1,A(m,n − 1)), m > 0, n > 0
A A
// POST: return value is the Ackermann function value A(m,n)
}
A(n, n) n A
http://www.cse-lab.ethz.ch
http://www.cse-lab.ethz.ch
Swiss Federal Institute of Technology Zurich Politecnico federale di Zurigo Ecole polytechnique federale de Zurich´ ´
Informatik fur Mathematiker und Physiker Serie 10 HS10
http://www.ti.inf.ethz.ch/ew/courses/Info1 10/
k + n!1
,
k
n!1
Skript-Aufgabe 116 (6 Punkte)
(20), (10, 10), (10, 5, 5), (5, 5, 5, 5)
4
partition.cpp
// PRE: [first , last) is a valid nonempty range that describes // a sequence of denominations d_1 > d_2 > ... > d_n > 0 // POST: return value is the number of ways to partition amount // using denominations from d_1 , ..., d_n unsigned int partitions (unsigned int amount ,
const unsigned int* first , const unsigned int* last);
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
Σ = {F,+,−} s = F + F + F + F P
F → FF + F + F + F + F + F − F.
Σ = {X, Y,+,−} s = Y P
X → Y + X + Y
Y → X − Y − X.
α = 60 X Y
Exercise 124 1, 2, 3
n
2 3 (2, 3) hanoi.cpp
n n = 2 (1, 2)(1, 3)(2, 3)
n = 3
2k < n < 2k+1
2 ≤ 2k2k−1 ≤ n
http://www.cse-lab.ethz.ch
• Teile Array in zwei Hälften
• Herrsche • Sortiere eine Hälfte, dann die andere
• Führe beide Hälften zusammen (Merge)
22
http://www.cse-lab.ethz.ch
23
Sort the following numbers using the merge sort algorithm. 38, 27, 43, 3, 9, 82, 10
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
http://www.cse-lab.ethz.ch
• T(n) ≤ (n-1)(log2 n)
http://www.cse-lab.ethz.ch
Komplexitätsanalyse
26
!"#$"%&'#()*+,-./"0(
' 1&*$02( 3 45*6*7*3*4!5 89"6*:*3 4#5 89$6*:*5 %;
7*4!5 89" %;6*#2'$ !5 89" $ :7*4!5 89" %;6*#2'$9*!5 89" $ : 4#5 89$ %;6*#2'$9*#5 89$ $ :*5 %; 7*4!5 89" %;6*4*#2'$9*5 $ % ;6*: 4#5 89$ %;6*4*#2'$9*5 $ % ;*6:*5 %; 7*45 < ;6*4*#2'$9*5 $ % ;6*:*5 %; =*45 < ;6*4*#2'$9*5 $ 6
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
Beispiele
27
// PRE: [first, last) is a valid range // POST: the elements *p, p in [first, last) are in //! ascending order void merge_sort (int* first, int* last) { ! int n = last - first; ! if (n <= 1) return;! ! ! // nothing to do ! int* middle = first + n/2; ! merge_sort (first, middle);! // sort first half ! merge_sort (middle, last);!! // sort second half ! merge (first, middle, last);! // merge both halves }
// PRE: [first, middle), [middle, last) are valid ranges; in // both of them, the elements are in ascending order void merge (int* first, int* middle, int* last) { ! int n = last - first; // total number of cards ! int* deck = new int[n]; // new deck to be built ! ! int* left = first;!! // top card of left deck ! int* right = middle;! // top card of right deck ! ! for (int* d = deck; d != deck + n; ++d) ! ! // put next card onto new deck ! ! if (left == middle) *d = *right++;! // left deck is empty ! ! else if (right == last)! *d = *left++;! // right deck is empty ! ! else if (*left < *right) *d = *left++;!! // smaller top card left ! ! else! *d = *right++;! ! // smaller top card right ! ! // copy new deck back into [first, last) ! int *d = deck; ! while (first != middle) *first++ = *d++; ! while (middle != last) *middle++ = *d++; ! ! delete[] deck; }
Tuesday, November 30, 2010
http://www.cse-lab.ethz.ch
x
// PRE: [first , last) is a valid range , and the elements *p, // p in [first , last) are in ascending order // POST: return value is a pointer p in [first , last) such // that *p = x, or the pointer last , if no such pointer // exists const int* binary_search (const int* first , const int* last , const int x) {
const int n = last - first; if (n == 0) return last; // empty range if (n == 1) {
if (*first == x) return first;
else return last;
} // n >= 2 const int* middle = first + n/2; if (* middle > x) {
// x can’t be in [middle , last) const int* p = binary_search (first , middle , x); if (p == middle)
return last; // x not found else
return p; } else
}
Abgabe: