这段代码是否遵循递归的定义?

发布于 2024-09-05 16:35:59 字数 2089 浏览 4 评论 0原文

我有一段代码,我怀疑它是否是其定义的递归实现。我的理解是代码必须调用自身,完全相同的函数。我还质疑以这种方式编写代码是否会增加额外的开销,这可以通过使用递归来看到。你有什么想法?

class dhObject
{
public:
   dhObject** children;
   int numChildren;
   GLdouble linkLength; //ai 
   GLdouble theta; //angle of rot about the z axis
   GLdouble twist; //about the x axis
   GLdouble displacement; // displacement from the end point of prev along z
   GLdouble thetaMax;
   GLdouble thetaMin;
   GLdouble thetaInc;
   GLdouble direction;

   dhObject(ifstream &fin)
   {
      fin >> numChildren >> linkLength >> theta >> twist >> displacement >> thetaMax >> thetaMin;
      //std::cout << numChildren << std::endl;
      direction = 1;
      thetaInc = 1.0;
      if (numChildren > 0)
      {
         children = new dhObject*[numChildren];
         for(int i = 0; i < numChildren; ++i)
         {
            children[i] = new dhObject(fin);
         }
      }
   }

   void traverse(void)
   {
      glPushMatrix();
      //draw move initial and draw
      transform();
      draw();
      //draw children
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->traverse();
      }
      glPopMatrix();
   }

   void update(void)
   {
      //Update the animation, if it has finished all animation go backwards
      if (theta <= thetaMin)
      {
         thetaInc = 1.0;
      } else if (theta >= thetaMax)
      {
         thetaInc = -1.0;
      }
      theta += thetaInc;
      //std::cout << thetaMin << " " << theta << " " << thetaMax << std::endl;
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->update();
      }
   }

   void draw(void)
   {
      glPushMatrix();
      glColor3f (0.0f,0.0f,1.0f);
      glutSolidCube(0.1);
      glPopMatrix();
   }

   void transform(void)
   {
      //Move in the correct way, R, T, T, R
      glRotatef(theta, 0, 0, 1.0);
      glTranslatef(0,0,displacement);
      glTranslatef(linkLength, 0,0);
      glRotatef(twist, 1.0,0.0,0.0);
   }
};

I have a piece of code which I am doubting it as a implementation of recursion by its definition. My understanding is that the code must call itself, the exact same function. I also question whether writing the code this way adds additional overhead which can be seen with the use of recursion. What are your thoughts?

class dhObject
{
public:
   dhObject** children;
   int numChildren;
   GLdouble linkLength; //ai 
   GLdouble theta; //angle of rot about the z axis
   GLdouble twist; //about the x axis
   GLdouble displacement; // displacement from the end point of prev along z
   GLdouble thetaMax;
   GLdouble thetaMin;
   GLdouble thetaInc;
   GLdouble direction;

   dhObject(ifstream &fin)
   {
      fin >> numChildren >> linkLength >> theta >> twist >> displacement >> thetaMax >> thetaMin;
      //std::cout << numChildren << std::endl;
      direction = 1;
      thetaInc = 1.0;
      if (numChildren > 0)
      {
         children = new dhObject*[numChildren];
         for(int i = 0; i < numChildren; ++i)
         {
            children[i] = new dhObject(fin);
         }
      }
   }

   void traverse(void)
   {
      glPushMatrix();
      //draw move initial and draw
      transform();
      draw();
      //draw children
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->traverse();
      }
      glPopMatrix();
   }

   void update(void)
   {
      //Update the animation, if it has finished all animation go backwards
      if (theta <= thetaMin)
      {
         thetaInc = 1.0;
      } else if (theta >= thetaMax)
      {
         thetaInc = -1.0;
      }
      theta += thetaInc;
      //std::cout << thetaMin << " " << theta << " " << thetaMax << std::endl;
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->update();
      }
   }

   void draw(void)
   {
      glPushMatrix();
      glColor3f (0.0f,0.0f,1.0f);
      glutSolidCube(0.1);
      glPopMatrix();
   }

   void transform(void)
   {
      //Move in the correct way, R, T, T, R
      glRotatef(theta, 0, 0, 1.0);
      glTranslatef(0,0,displacement);
      glTranslatef(linkLength, 0,0);
      glRotatef(twist, 1.0,0.0,0.0);
   }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

源来凯始玺欢你 2024-09-12 16:35:59

这是一个定义/挑剔的问题。在这个 C 函数中:

void traverse( tree * t ) {
    if ( t != 0 ) {
        traverse( t->right );
        traverse( t->left );
    }
}

该函数是递归的吗?我会说是的,即使它是在不同的对象上调用的。所以我想说你的代码也是递归的。举一个更极端的例子:

unsigned int f( unsigned int n ) {
    if ( n = 0 ) {
       return 0; 
    }
    else {
       return f( n - 1 );   // XXX
    }
}

在 XXX 处调用该函数的对象显然与最初调用它的对象不同。但我想每个人都会同意这是一个递归函数。

This is a matter of definition/nitpicking. In this C function:

void traverse( tree * t ) {
    if ( t != 0 ) {
        traverse( t->right );
        traverse( t->left );
    }
}

Is the function recursive? I would say yes, even though it is being called on different objects. So I would say your code is also recursive. To take an even more extreme example:

unsigned int f( unsigned int n ) {
    if ( n = 0 ) {
       return 0; 
    }
    else {
       return f( n - 1 );   // XXX
    }
}

The thing the function is being called on at XXX is obviously not the same thing it was originally called on. But I think everyone would agree this is a recursive function.

看轻我的陪伴 2024-09-12 16:35:59

是的,因为您有某些函数会调用自己。根据定义,这是直接递归。如果你有函数A()调用函数B(),函数B(),你也可以有间接递归 > 依次(直接或间接)再次调用函数A()

Yes, since you have certain functions calling themselves. By definition that is direct recursion. You could also have indirect recursion if you had function A() calling function B(), function B() in turn (directly or indirectly) calling function A() again.

绝影如岚 2024-09-12 16:35:59

看起来像 traverse() 和 update() 方法中的递归,其深度由对象集合的物理几何形状控制。

如果这是您的实际课程,我会建议您执行以下操作:

  1. 在使用 numChildren 之前检查它的上限,以免有人错误地传入非常大的数字。

  2. 如果这将在线程环境中使用,您可能希望同步对子对象的访问。

    如果这

  3. 考虑使用容器而不是分配数组。我也没有看到析构函数,因此如果删除该对象,您将泄漏数组存储和子对象的内存。

Looks like recursion in the traverse() and update() methods with depth controlled by the physical geometry of your object collection.

If this is your actual class I would recommend a few things:

  1. Check the upper bound of numChildren before using it lest someone passes in a remarkably huge number by mistake.

  2. If this will be used in a threaded environment you might want to synchronize access to the child objects.

  3. Consider using containers instead of allocating an array. I don't see a destructor either so you'd leak the memory for the array storage and the children if this object gets deleted.

残龙傲雪 2024-09-12 16:35:59

如果您担心的只是递归的开销,那么重要的是衡量堆栈的深度。如果您的堆栈有 100 个调用深度,则无论是否递归工作都没有关系。

If all you're worried about is the overhead of recursion then the important thing is to measure how deep your stack goes. It doesn't matter whether you're working recursively or not, if your stack is 100 calls deep.

ぶ宁プ宁ぶ 2024-09-12 16:35:59

调用这些方法之一(遍历或更新)将具有对每个子项调用相同方法的效果。因此,这些方法不是递归的。相反,它是一种递归算法:它递归地应用于对象的逻辑树。

调用堆栈的深度直接由算法运行的数据结构决定。

真正发生的事情是这样的(伪代码):

Function Traverse(object o)
{
   [do something with o]

   Foreach(object child in o.Children)
       Traverse(child);

   [do something with o]
}

Calling one of these methods(traverse or update) will have the effect of calling that same method an every child. So, the methods are not recursive. Instead, it's a recursive algorithm: it is applied recursively on the logical tree of objects.

The depth of the call stack is directly determined by the structure of the data on which the algorithm operates.

What really happens is this(pseudo code):

Function Traverse(object o)
{
   [do something with o]

   Foreach(object child in o.Children)
       Traverse(child);

   [do something with o]
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文