Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Является ли данный код рекурсивным?

#cpp #рекурсия


Есть задание 

Найти методом деления отрезка пополам минимум функции f(x) = 7sin(2x) на отрезке
[2, 6] с заданной точностью ε (например, 0.01).
Разумеется, его нужно написать 

#include 
#include 
#include 
using namespace std;


const double eps = 0.01;
double a, b, t, x, y, t1, s;

double func(double a, double b)
{
    s = (a + b) / 2;
    y = (7 * sin(2)*s);
    return y;
}

int main()
{
    a = 2;
    b = 6;
    while (abs(b - a) < eps);
    {
        t = (a + b) / 2.0;
        y = 7 * sin(2)*(t - eps);
        x = 7 * sin(2)*(t + eps);
        if (y <= x)
        {
            a = t;
            t1 = func(a, b);
        }
        else
        {
            b = t;
            t1 = func(a, b);
        }
    }
    cout << "Otvet: " << t1;
    return 0;
}


Проблема в том, что преподаватель говорит, что задача решена не рекурсивно. Я утверждаю
что решение рекурсивно, так как функция double func принимает значение из функции int
main. Прав ли я?
    


Ответы

Ответ 1



Верно будет так (примерны код): rec(double a, double b){ (здесь все ваши действия с синусами) if (abs(b - a) < eps) // проверяем новые значения - надо еще раз пересчитать? rec(a, b) // вызываем саму себя с новыми значениями else return ... // иначе - возвращаем ответ } И в мейне вызываем эту функцию,не забыв передать в нее начальные a и b

Ответ 2



Нет, это решение не является рекурсивным. Рекурсия предполагает вызов функции из себя (прямо или косвенно), а в приведённом решении ничего подобного нет. Более того, приведённое решение визуально кажется мне неверным. Функция не является монотонной, поэтому всякие шаманства со знаками применять, скорее всего, не следует. На мой взгляд, правильным будет проверять весь отрезок полностью (в условии сказано "методом деления отрезка пополам", но не сказано, что это должен быть бинпоиск, отсекающий половину отрезка). http://ideone.com/fyRCVW #include #include using namespace std; const double EPS = .01; double f(double x) { return 7 * sin(2*x); } double solve(double l, double r) { double m = l / 2 + r / 2; if (r-l < EPS) return m; double x1 = solve(l, m), x2 = solve(m, r); return f(x1) < f(x2) ? x1 : x2; } int main() { cout << solve(2, 6); return 0; } Ответ: 2.35547.

Ответ 3



Рекурсия достигается в вашем случае с изменением "входимости кода" на уровень выше. Оберните цикл while (точнее, замените цикл на рекурсивный вызов) в функцию, и будет вам то, что хочет препод. Вот готовое решение: // Найти методом деления отрезка пополам минимум функции f(x) = 7sin(2x) на отрезке [2, 6] с заданной точностью ε (например, 0.01). #include #include #include using namespace std; const double eps = 0.01; double a, b, t, x, y, t1, s; double func(double a, double b, double e) { s = (a + b) / 2 ; t1 = 7 * sin(2*s + e) ; return t1; } void JustDoIt(double &a,double &b) { t = (a + b) / 2.0; y = func(a, b, - eps); x = func(a, b, eps); if (y >= x) a = t; else b = t; // чек-блок cout << "t= " << t <<"\n"; cout << "a= " << a <<" b=" << b <<"\n"; cout << "x= " << x <<" y=" << y <<"\n"; cout << "fabs(b - a)= " << fabs(b - a) <<"\n"; // if ( fabs(b - a) < eps) return; JustDoIt( a, b); } int main() { a = 2; b = 6; JustDoIt( a, b); cout << "Otvet: " << func(a, b,0)<<"\n"; return 0; } Вывод: a= 4 b=6 x= 6.91498 y=6.93535 fabs(b - a)= 2 a= 5 b=6 x= -3.86669 y=-3.74922 fabs(b - a)= 1 a= 5 b=5.5 x= -6.99927 y=-6.99989 fabs(b - a)= 0.5 a= 5.25 b=5.5 x= -6.19085 y=-6.12428 fabs(b - a)= 0.25 a= 5.375 b=5.5 x= -6.80666 y=-6.77263 fabs(b - a)= 0.125 a= 5.4375 b=5.5 x= -6.95725 y=-6.94041 fabs(b - a)= 0.0625 a= 5.46875 b=5.5 x= -6.99191 y=-6.98379 fabs(b - a)= 0.03125 a= 5.48438 b=5.5 x= -6.99901 y=-6.99525 fabs(b - a)= 0.015625 a= 5.49219 b=5.5 x= -6.99999 y=-6.99843 fabs(b - a)= 0.0078125 Otvet: -6.99996 попутно выявились ошибки в вашем коде: while не выполняется из-за ";" , а блок затем проходит только один раз и вместо abs() нужно использовать fabs().

Ответ 4



#include #include #include using namespace std; const double eps = 0.01; double a, b, t, x, y, t1, s; double func(double a, double b) { s = (a + b) / 2; t1 = (7 * sin(2)*s); return t1; } double rec(){ while (abs(b - a) < eps); { t = (a + b) / 2.0; y = 7 * sin(2)*(t - eps); x = 7 * sin(2)*(t + eps); if (y <= x) { a = t; t1 = func(a, b); } else { b = t; t1 = func(a, b); } } } int main() { a = 2; b = 6; rec(); cout << "Otvet: " << t1; return 0; }

Комментариев нет:

Отправить комментарий