Добавил:
Оставь надежду всяк сюда поступивший Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
22
Добавлен:
13.01.2019
Размер:
84.53 Кб
Скачать

Рекурсия

Решение вычисление факториала целого положительного числа

// Оператора using namespace std нет. Поэтому используется .h

#include <iostream.h>

#include <windows.h>

#include <stdlib.h>

// Функция для вычисления факториала неотрицательного числа

int factorial( int number );

/* Функция преобразования символьной строки из кодировки Windows в кодировку DOS.*/

char* rus_str( char* str );

// Начало определения главной функции

int main()

{

int whole_number;

cout << rus_str( "Введите положительное целое число :\n" );

cin >> whole_number;

cout << rus_str( "Факториал числа " ) << whole_number;

cout << rus_str( " равен " )

<< factorial( whole_number ) << ".\n";

char wait_char;

cin >> wait_char;

return 0;

}

// Конец главной функции

// Начало определения функции "factorial"

int factorial(int number)

{

if ( number < 0 )

{

cout << rus_str( "\n Ошибка - отрицательный аргумент факториала \ n" );

exit( 1 );

}

else if ( number == 0 )

return 1;

return number*factorial( number - 1 );

}

// Конец определения функции

// Начало определения функции "rus_str"

char* rus_str( char* str )

{

static char sBuf[256];

CharToOem( str, sBuf );

return sBuf;

}

// Конец определения функции

  1. Написать рекурсивную функцию для нахождения биномиальных коэффициентов, пользуясь их определением

Cmn =

Вычислить для k = 2, 4, 6, 8.

  1. Задано конечное множество имен жителей некоего города, причем для каждого из жителей перечислены имена его детей. Жители X и Y называются родственниками, если а) либо X – ребенок Y, б) либо Y – ребенок X, в) либо существует некий Z такой, что X является родственником Z, а Я является родственником Y. Перечислить все пары жителей города, которые являются родственниками.

  2. Подсчитать количество различных представлений заданного натурального n в виде суммы не менее двух попарно различных положительных слагаемых. Представления, отличающиеся лишь порядком слагаемых, различными не считаются.

  3. Напечатать поле для игры в шахматы, в котором черные поля изображаются квадратами, заполненными 5 × 5 = 25 звездочками (символами ’*’).

  4. Вычислить определить заданной матрицы, пользуясь формулой разложения по первой строке: detA = , где матрица Bk получается из A вычеркиванием первой строки и k – го столбца.

  5. Напишите две функции вычисления i – го числа Фибоначчи – рекурсивную и нерекурсивную – и напечатайте таблицу для сравнения времен вычисления i – го числа Фибоначчи для i = 4, 6, 8, 10, 12 с помощью этих функций. Используйте для этого стандартную функцию CLOCK – функцию без параметров, которая выдает целое число, равное времени (в миллисекундах) центрального процессора, уже использованного Basic-программой.

  6. Функция f(n) определена для целых положительных чисел следующим образом:

f(n) = Вычислить f(k) для k = 15, 16, …, 30.

  1. Для заданного целого N вычислить значение суммы с помощью рекурсивной функции.

  2. Функция A преобразования текста определяется следующим образом Ф(α) = Реализовать функцию Ф с помощью рекурсивной процедуры.

  3. Функция Ф преобразования вектора целых k определяется следующим образом:

Ф(α) = Отметим, что функция Ф преобразует вектор, не меняя его длину. Реализовать функцию Ф с помощью рекурсивной процедуры. Пример: Ф(1, 2, 3, 4, 5, 6, 7) = 1, 2, 3, 4, 5, 6, 7.

Решение Рекурсивные функции. Работа со строками.

Функция Ф преобразования вектора целых k определяется следующим образом:

Ф(α) =

Отметим, что функция Ф может удлинять вектор. Реализовать функцию Ф с помощью рекурсивной процедуры.

Примеры: Ф(1, 2, 3, 4, 5, 6, 7, 8, 9) = 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9;

Ф(1, 2, 3, 4, 5, 6, 7, 8) = 1, 2, 3, 4, 5, 6, 7, 8.

Математическая модель не приводится

//Программа преобразования вектора

#include <fstream>

#include <iostream>

#include <string>

using namespace std;

string F( const string& InStr); //Заголовок функции преобразования

int main()

{

string StrRes, S;

ifstream fin("infile.txt");

if (!fin) {cout << "It is file open mistake." << endl; return 1;}

getline(fin, StrRes); //Чтение строки из файла

StrRes = F(StrRes);

cout << "The result is : " << StrRes << endl;

return 0;

}

string F(const string& InStr) //Тело функции преобразования строки

{

string S, S1; int mLength=InStr.length(); // Длина входной строки

int mHalf = mLength/2;

if (mLength<=2)

return InStr;

if (mLength % 2) //Нечетная длина строки

{

S = InStr.substr(0, mHalf+1); //Половина строки + средний элемент

S = F(S);

S1 = InStr.substr(mHalf, mHalf +1); // Средний элемент + вторая половина строки

S += F(S1); //суммирование строк

return S;

}

else //Четная длина строки

{

S = InStr.substr(0, mHalf);

S = F(S);

S1 = InStr.substr(mHalf, mHalf);

S += F(S1); //суммирование строк

return S;

}

}

Замечания по отладке программы

Первый прогон нужно выполнить с файлом 123. Для входа в функцию применить клавишу F11.

  1. Построить синтаксический анализатор для понятия «предложение»:

предложение ::=

слово ::=

разделитель ::=

Математическая модель

Предложение является строкой состоящей из слов. Слова разделены одним или несколькими пробелами.

Нужно построить рекурсивные функции: Предложение, Слово и Разделитель. Для простоты примем, что буквы могут принадлежать только английскому алфавиту.

  1. Построить синтаксический анализатор для понятия простое - выражение:

простое-выражение ::=

простой-идентефикатор ::= буква

знак-операции ::=

  1. Построить синтаксический анализатор для понятия идентификатор:

идентификатор ::=

  1. Построить синтаксический анализатор для понятия вещественное-число:

вещественное-число ::=

целое-без-знака ::= цифра{цифра}*

целое-число ::=

  1. Построить синтаксический анализатор для понятия простое-логическое:

простое-логическое ::=

простой идентификатор ::= буква

знак-операции ::=

  1. Написать программу, которая по заданному простому-логическому выражению (определение понятия содержится в формулировке предыдущей задачи), не содержащему вхождений простых идентификаторов, вычисляет и печатает значение этого выражения.

  2. Построить синтаксический анализатор для понятия константное-выражение:

константное-выражение ::=

  1. Написать программу, которая по заданному константному-выражению (определение понятия содержится в формулировке предыдущей задачи) вычисляет и печатает либо значение этого выражения, либо сообщение «при вычислении константного выражения получен промежуточный результат, превосходящий по модулю миллион».

Решение Построить синтаксический анализатор для понятия скобки.

скобки ::=

квадр ::=

кругл ::=

Правильно написанными скобками являются, например, строки [--]; ([--]+), а строка [-] не является скобкой.

Математическая модель

Диаграмма объекта скобки

Квадратная

Круглая

Процедуры Квадр и Кругл управляются первым символом текущей строки разбора. Первой вызываемой процедурой является Скобки.

Псевдокод не приводится, поскольку понятен из текста программы.

Текст программы Скобки

// Brackets

#include <fstream>

#include <iostream>

#include <string>

using namespace std;

bool pBrackets(); //Скобки

bool pSquare(); //Квадратные скобки

bool pRound(); //Круглые скобки

void pstep(); //Переход к следующему символу строки

void pMist(const string& InName); //Обработка ошибки

string S;

int main()

{

ifstream fin("infile.txt"); //Объявление файла

if (!fin) {cout << "It is file open mistake." << endl; return 1;}

getline(fin, S); //Чтение строки из файла

if (pBrackets())

{cout << "The result is true: " << endl;}

return 0;

}

bool pBrackets()

{

if ((S[0]=='[') || (S[0]=='+'))

{pSquare(); return 0;}

if ((S[0]=='(') || (S[0]=='-'))

{pRound();return 0;

}

pMist("pBrackets"); //Обработка ошибки

return 1;

}

bool pSquare()

{

if (S[0]=='[')

{

pstep(); //Переход к следующему символу строки

pRound();

pRound();

if (S[0]==']') {pstep();return 0;}

else pMist("pRound");

}

if (S[0] == '+') {pstep();return 0;}

pMist("pRound");

return 1;

}

bool pRound()

{

if (S[0]=='(')

{

pstep();//Переход к следующему символу строки

pSquare();

pSquare();

if (S[0]==')') {pstep();return 0;}

else pMist("pRound");

}

if (S[0]=='-') {pstep();return 0;}

pMist("pRound");

return 1;

}

void pstep()

{

S = S.substr(1);

}

void pMist(const string& InName)

{

cout << "Mistake is in : " << InName << " with " << "\"" << S <<"\"\n";

}

  1. Построить синтаксический анализатор для понятия список-списков:

список-списков ::= список {; список}*

список ::= элемент {, элемент}*

элемент ::= буква

  1. Построить синтаксический анализатор для понятия скобки:

скобки ::=

кругл ::=

квадр ::=

  1. Построить синтаксический анализатор для понятия сумма:

сумма ::= целое{знак-операции целое}*

целое ::= цифра{цифра}*

знак-операции ::=

Например, 021 + 16 и 22- суммы, а +1 –не сумма.

  1. Написать программу, которая по заданной сумме (определение понятия содержится в формулировке предыдущей задачи) вычисляет и печатает либо значение этой суммы, либо сообщение «при вычислении суммы получен промежуточный результат, превосходящий по модулю миллион».