2013-05-13 126 views
4

这是一个家庭作业问题。我无法转换成如下递归函数:将循环转换为递归函数

public class Integrate { 
    public static double integrate(int a, int b, int steps) 
    { 
     double sum=0; 
     double delta = 1.0 * (b - a)/steps; 
     double x = a; 
     double f = 0.5*x*x + 3*x + 5; 

     for (int i = 0; i< steps; i++) 
     { 
      x = x + delta; 
      double fr = 0.5*x*x + 3*x + 5; 
      double area = f * delta + 0.5*(fr - f)*delta; 
      sum += area; 
      f = fr; 
     } 
     return sum; 
    } 
    public static void main(String [] args) 
    { 
     int a, b, step; 
     a = Integer.parseInt(args[0]); 
     b = Integer.parseInt(args[1]); 
     step = Integer.parseInt(args[2]); 
     System.out.format("Integral is %f\n", integrate(a,b,step)); 
    } 
} 

这是我迄今为止,但输出是不一样的原代码。我无法弄清楚什么是错的

public class Integrate { 

    public static double integrate(int a, int b, int steps) { 
     double sum=0; 
     int i=0; 
     sum = rintegrate(a, b, steps, i, sum); 
     return sum; 
    } 

    public static double rintegrate(int a, int b, int steps, 
      int i, double sum) { 
     double delta = 1.0 * (b - a)/steps; 
     double x = a; 
     double f = 0.5*x*x + 3*x + 5; 
     if (i<steps) { 
      x = x + delta; 
      double fr = 0.5*x*x + 3*x + 5; 
      double area = f * delta + 0.5*(fr - f)*delta; 
      sum += area; 
      f = fr; 
      i++; 
      rintegrate(a, b, steps, i, sum); 
     } 
     return sum; 
    } 

    public static void main(String[] args) { 
     int a, b, step; 
     a = Integer.parseInt(args[0]); 
     b = Integer.parseInt(args[1]); 
     step = Integer.parseInt(args[2]); 
     System.out.format("Integral is %f\n", integrate(a,b,step)); 
    } 

} 
+0

什么是你的原码输出?以及新代码的输出是什么? – 2013-05-13 16:11:34

+3

看起来你没有使用你的'rintegrate'的递归值递归地... – 2013-05-13 16:12:10

+0

a = 1,b = 10,step = 1000 .......原来出来360.000061和我的输出0.076662 – user2378481 2013-05-13 16:15:30

回答

3

我不打算全面分析这个问题,但这里有一些意见,我有间sum += area;return sum;是多余的

if (i<steps) { 
     x = x + delta; 
     double fr = 0.5*x*x + 3*x + 5; 
     double area = f * delta + 0.5*(fr - f)*delta; 
     sum += area; 
     f = fr; 
     i++; 
     rintegrate(a, b, steps, i, sum); 
    } 
    return sum; 

一切。

  • 你设置ffr,但你从来没有使用后f。如果你想f下次不同,也许你可以将它作为参数传递给你的递归函数
  • 你递归地调用rintegrate(...),但是你没有对它返回的值做任何事情。你可能想要使用该值。

你应该考虑递归作为使用问题的一个较小的版本来解决本身。

这里是你的问题,假设你有一个函数一些代码:segment,只是计算给出a第一段的大小,delta

rintegrate(a, b, steps) 
{ 
    if(steps <= 1) 
    { 
     delta = b-a; 
     return segment(a, delta) 
    } 
    else 
    { 
     delta = (b-a)/steps 
     return segment(a, delta) + rintegrate(a+delta, b, steps-1) 
    } 
} 
+0

你的榜样删除代码,它与步骤计算,然后下去?有没有办法做到这一点从0开始? – user2378481 2013-05-13 16:50:56

+0

@ user2378481你仍然在反复思考这个问题。尝试递归思考问题。您的功能需要添加一个细分,并添加到其他细分的总和中,然后返回该值 – 2013-05-13 16:53:07

+0

这仍然很难理解。这是否像继续前一步的一切?对不起,递归对我来说看起来像一个循环。 – user2378481 2013-05-13 17:06:26

1

工作版本

只要复制粘贴你会得到与你原来的方法相同的输出。

public static void main(String[] args) { 
     int a = 1, b = 10, step = 1000; 
      double delta = 1.0 * (b - a)/step; 
     double sum = integrate(a, b, step, 0, 0, 0, delta); 
     double test = working(a, b, step); 
     System.out.println("Integral is " + sum); 
     System.out.println("Integral is " + test); 
    } 

工作递归版本:

public static double integrate(double x, int b, int steps, int i, 
      double sum, double f, double delta) { 
     f = 0.5 * x * x + 3 * x + 5; 
     if (i < steps) { 
      x = x + delta; 
      double fr = 0.5 * x * x + 3 * x + 5; 
      double area = f * delta + 0.5 * (fr - f) * delta; 
      return integrate(x, b, steps, i + 1, sum + area, fr, delta); 
     } 
     return sum; 
    } 

你原来的迭代方法;

public static double working(int a, int b, int steps) { 
    double sum = 0; 
    double delta = 1.0 * (b - a)/steps; 
    double x = a; 
    double f = 0.5 * x * x + 3 * x + 5; 

    for (int i = 0; i < steps; i++) { 
     x = x + delta; 
     double fr = 0.5 * x * x + 3 * x + 5; 
     double area = f * delta + 0.5 * (fr - f) * delta; 
     sum += area; 
     f = fr; 
    } 
    return sum; 
} 
+0

的基本情况嗨,谢谢你的帮助。你的代码也没有给出正确的输出。 hw问题被称为整合的整合,这就是为什么我首先使用了整合方法。 – user2378481 2013-05-13 16:44:55

+0

我明白了。你的作品现在。这有点不是我在找的东西,但有助于看到我的问题。我不明白你的版本在哪里计算三角洲? – user2378481 2013-05-13 17:09:59

+0

谢谢,我现在有一个工作解决方案,通过在递归方法之外声明delta和x。但是,为什么他们之间的调用会有所不同,如果没有与它们相关的变量被改变? – user2378481 2013-05-13 17:33:54

0

这是你想要的东西;)

public class Integrate{ 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     int a, b, step; 
     a = Integer.parseInt(args[0]); 
     b = Integer.parseInt(args[1]); 
     step = Integer.parseInt(args[2]); 
     System.out.format("Integral is %f\n", 
       adaptiveSimpsons(a, b, step)); 

    } 

    private static double f(double i) { 
     return (0.5 * i * i + 3 * i + 5); 
    } 

    static double adaptiveSimpsons(double a, double b, // interval [a,b] 
      int maxRecursionDepth) { // recursion cap 
     double c = (a + b)/2, h = b - a; 
     double fa = f(a), fb = f(b), fc = f(c); 
     double S = (h/6) * (fa + 4 * fc + fb); 
     return adaptiveSimpsonsAux(a, b, S, fa, fb, fc, maxRecursionDepth); 
    } 

    private static double adaptiveSimpsonsAux(double a, double b, double S, double fa, 
      double fb, double fc, int bottom) { 
     double c = (a + b)/2, h = b - a; 
     double d = (a + c)/2, e = (c + b)/2; 
     double fd = f(d), fe = f(e); 
     double Sleft = (h/12) * (fa + 4 * fd + fc); 
     double Sright = (h/12) * (fc + 4 * fe + fb); 
     double S2 = Sleft + Sright; 
     if (bottom <= 0) 
      return S2 + (S2 - S)/15; 
     return adaptiveSimpsonsAux(a, c, Sleft, fa, fc, fd, bottom - 1) 
       + adaptiveSimpsonsAux(c, b, Sright, fc, fb, fe, bottom - 1); 
    } 
} 

测试和工作

转换过来的C代码中给出here

+0

我认为你在错误的地方 – user2378481 2013-05-13 17:07:00

+0

不,你正在尝试做递归整合可以递归使用辛普森算法来进行登载,因此该方法被命名的方式。你甚至看过代码吗?如OP中所述,它递归地将函数0.5x^2 + 3x + 5集成到给定数量的步骤。如果您将我的代码复制到eclipse并运行它,您会看到它递归计算所需的积分... – o0rebelious0o 2013-05-13 17:11:52