首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归算法与事件驱动使用者之间的协调模式

递归算法与事件驱动使用者之间的协调模式
EN

Stack Overflow用户
提问于 2014-03-31 11:57:15
回答 1查看 108关注 0票数 1

考虑河内塔问题的经典递归伪码解决方案:

代码语言:javascript
复制
  void move(num,src,dest,spare) {
      if(num == 1) {
         moveSingle(src,dest);
      } else {
         move(num-1,src,spare,dest);
         move(1,src,dest,spare);
         move(num-1,spare,dest,src);
      }
  }

..。并考虑显示引擎(如处理)中的事件循环。

代码语言:javascript
复制
  void draw() {
      // code to draw a single frame goes here; for example
      if(! aDiscIsInMotion()) {
          getNextMove();
      }

      updateCoordinates();
      drawMovingDisc();
  }

这两者之间有什么模式可以协调呢?

我想到了两个选择:

线程和队列

在自己的线程中启动递归函数。moveSingle()将一个移动写入FIFO队列。如果队列有容量,这可能会阻塞。getNextMove()读取队列中的移动。

我确信这很好,但我很好奇是否有一种模式可以避免线程。

使用显式堆栈而不是递归

重写递归算法以在堆中使用LIFO队列,而不是调用堆栈。类似于:

代码语言:javascript
复制
 Move getMove() {
     if(lifo.isEmpty()) {
         return null;
     }
     State state = lifo.pop();
     while(state.num != 1) {
         lifo.push(new State(state.num -1, state.spare, state.dest, state.src));
         lifo.push(new State(1, state.src, state.dest, state.spare));
         lifo.push(new State(state.num -1, state.src, state.spare, state.dest));
         state = lifo.pop();
     }
     return new Move(state); // guaranteed num==1
 }

..。这同样有效,但是我们失去了使用调用堆栈来保持状态的递归的表达能力。

还有另一种我没发现的技术吗?

注意,虽然我选择了河内塔和处理的例子,但这是一个将递归算法与希望轮询更新的另一个接口集成的一般问题。所以我对“你不需要一堆东西来解决河内”这样的答案不感兴趣--我知道。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-31 12:02:38

您要寻找的是协同,尽管它们在某些语言(例如Java)中缺失。Coroutines允许您在生成例程实际完成之前向调用例程屈服。我知道有一个Java库可以重写字节码以支持协同;如果您是针对Java的话,您将不得不研究它。

您提到的两个变体本质上是可供选择的:多线程或排队您想要产生的中间结果。在您的特定情况下,算法中没有交互,因此您可以预先创建整个队列,而不是在算法中进行检查。

编辑:,我不确定递归是否有那么好的效果;我的知识更多的是理论上的。不过,我认为您应该能够直接或通过在递归调用中额外地生成多个级别。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22760943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档