4. Рекурсия

План:
Триъгълни числа
Пермутации
Ефективност на рекурсията
Непряка (взаимна) рекурсия


** До сега за рекурсията
Записване на число с думи на английски език (7. Функции II)

** Триъгълни числа

// triangle.cpp
#include <iostream>
using namespace std
/** A class that describes triangle shapes like this: [] [][] [][][] . . . */
class Triangle { public: Triangle(int w); int get_area() const; private: int width;
}; /** Constructs a triangle with a given width. @param w the width of the triangle base */ Triangle::Triangle(int w) { width = w; } /** Computes the area of the triangle shape. @return the area */ int Triangle::get_area() const { if (width == 1) return 1; Triangle smaller_triangle(width - 1); int smaller_area = smaller_triangle.get_area(); return smaller_area + width; } int main() { Triangle t(4); cout << "Area: " << t.get_area() << endl; return 0; }
nkirov@cpp % c++ triangle.cpp
nkirov@cpp % ./a.out
Area: 10
nkirov@cpp %


**  Пермутации
// permute.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/**
   Computes n!
   @param n a nonnegative integer
   @return n! = 1 * 2 * 3 * . . . * n
*/
int factorial(int n)
{  if (n == 0) return 1;
   int smaller_factorial = factorial(n - 1);
   int result = smaller_factoria * n;
   return result;
}
/**
   Generates all permutations of the characters in a string
   @param word a string
   @return a vector that is filled with all permutations 
   of the word
*/
vector<string> generate_permutations(string word)
{  vector<string> result;
   if (word.length() == 1) 
{ result.push_back(word); return result; } for (int i = 0; i < word.length(); i++) { string shorter_word = word.substr(0, i) + word.substr(i + 1, word.length() - i - 1); vector<string> shorter_permutations
= generate_permutations(shorter_word); for (int j = 0; j < shorter_permutations.size(); j++) { string longer_word = word[i] + shorter_permutations[j]; result.push_back(longer_word); }
} return result; } int main() { cout << "Enter a string: "; string input; getline(cin, input);
cout << "There are " << factorial(input.length())
<< "permutations.\n"; vector<string> v = generate_permutations(input); for (int i = 0; i < v.size(); i++) cout << v[i] << endl; return 0; }
nkirov@cpp % ./a.out
Enter a string: eat
There are 6 permutations.
eat
eta
aet
ate
tea
tae
nkirov@cpp %


recursive dancing

** Ефективност на рекурсията
nkirov@cpp % ./a.out
Enter n: 30
fib(30) = 832040
nkirov@cpp % ./a.out
Enter n: 50
^C
nkirov@cpp %

nkirov@cpp % c++ fibloop.cpp
nkirov@cpp % ./a.out
Enter n: 30
fib(30) = 832040
nkirov@cpp % ./a.out
Enter n: 50
fib(50) = -298632863
nkirov@cpp %

** Непряка (взаимна) рекурсия (mutual recurson)
 // eval.cpp
 #include <iostream>
 using namespace std;

int term_value(); int factor_value(); /** Evaluates the next expression found in cin @return the value of the expression. */ int expression_value() { int result = term_value(); bool more = true; while (more) { char op = cin.peek(); if (op == '+' || op == '-') { cin.get(); int value = term_value(); if (op == '+') result = result + value; else result = result - value; } else more = false; } return result; } /** Evaluates the next term found in cin @return the value of the term. */ int term_value() { int result = factor_value(); bool more = true; while (more) { char op = cin.peek(); if (op == '*' || op == '/') { cin.get(); int value = factor_value(); if (op == '*') result = result * value; else result = result / value; } else more = false; } return result; } /** Evaluates the next factor found in cin @return the value of the factor. */ int factor_value() { int result = 0; char c = cin.peek(); if (c == '(')
{ cin.get(); result = expression_value(); cin.get(); // read ")" } else // assemble number value from digits { while (isdigit(c)) { result = 10 * result + c - '0'; cin.get(); c = cin.peek(); }
} return result; } int main() { cout << "Enter an expression: "; cout << expression_value() << endl; return 0; }
nkirov@cpp % ./a.out
Enter an expression: (3+4)*5
35
nkirov@cpp %