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

Method

Есть задание

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

#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;


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

****** func(****** a, ****** 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;
}
</stdlib.h></math.h></iostream>

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

4 ответа

Method

Верно будет так (примерны код):

rec(****** a, ****** b){
      (здесь все ваши действия с синусами)
      if (abs(b - a) < eps)  // проверяем новые значения - надо еще раз пересчитать?
            rec(a, b) // вызываем саму себя с новыми значениями
      else return ... // иначе - возвращаем ответ
  }

И в мейне вызываем эту функцию,не забыв передать в нее начальные a и b


Method

Нет, это решение не является рекурсивным. Рекурсия предполагает вызов функции из себя (прямо или косвенно), а в приведённом решении ничего подобного нет.

Более того, приведённое решение визуально кажется мне неверным. Функция не является монотонной, поэтому всякие шаманства со знаками применять, скорее всего, не следует.

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

http://ideone.com/fyRCVW

#include <iostream>
#include <cmath>

using namespace std;

const ****** EPS = .01;

****** f(****** x)
{
    return 7 * sin(2*x);
}

****** solve(****** l, ****** r)
{
    ****** m = l / 2 + r / 2;

    if (r-l < EPS)
        return m;

    ****** x1 = solve(l, m), x2 = solve(m, r);
    return f(x1) < f(x2) ? x1 : x2;
}

int main()
{
    cout << solve(2, 6);
    return 0;
}
</cmath></iostream>

Ответ: 2.35547.


Method

Рекурсия достигается в вашем случае с изменением "входимости кода" на уровень выше. Оберните цикл while (точнее, замените цикл на рекурсивный вызов) в функцию, и будет вам то, что хочет препод.

Вот готовое решение:

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

    #include <iostream>
    #include <math.h>
    #include <stdlib.h>
    using namespace std;

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

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

    void JustDoIt(****** &a,****** &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;
    }
</stdlib.h></math.h></iostream>

Вывод:

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().


Method

#include <iostream>
#include <math.h>
#include <stdlib.h>

using namespace std;


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

****** func(****** a, ****** b)
{
 s = (a + b) / 2;
 t1 = (7 * sin(2)*s);
 return t1;
}
****** 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;
 }
</stdlib.h></math.h></iostream>

licensed under cc by-sa 3.0 with attribution.