- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
考虑汉诺塔问题的这个经典递归伪代码解决方案:
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);
}
}
... 并考虑显示引擎中的事件循环,例如 Processing
void draw() {
// code to draw a single frame goes here; for example
if(! aDiscIsInMotion()) {
getNextMove();
}
updateCoordinates();
drawMovingDisc();
}
两者之间有什么模式可以协调?
我想到了两个选项:
线程和队列
在自己的线程中启动递归函数。 moveSingle() 将移动写入 FIFO 队列。如果队列已满,这可能会阻塞。 getNextMove() 从队列中读取一个 Action 。
我确信这工作正常,但我很好奇是否有避免线程的模式。
使用显式堆栈而不是递归
重写递归算法以在堆中使用 LIFO 队列,而不是调用堆栈。像这样的东西:
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
}
...再一次,这可行,但我们失去了使用调用堆栈来保存状态的递归表达能力。
是否还有其他我没有发现的技术?
请注意,虽然我选择了汉诺塔和 Processing 的示例,但这是将递归算法与另一个想要轮询更新的接口(interface)集成的一般问题。所以我对诸如“你不需要堆栈来解决 Hanoi”之类的回答不感兴趣——我知道这一点。
最佳答案
您正在寻找的是协同程序,尽管它们在某些语言(例如 Java)中缺失。协程让您在让出例程实际完成之前让出调用例程。我知道有一个 Java 库可以重写字节码以支持协程;如果您的目标是 Java,则必须研究它。
您提到的两个变体本质上是替代方案:多线程或排队您想要产生的中间结果。在您的特定情况下,您的算法中没有交互,因此您实际上可能会提前创建整个队列,而不是检查您的算法内部。
编辑: 我不确定 yield 是否适用于递归;我的知识比较理论化。不过,我认为您应该能够直接或通过在递归调用中额外产生多个级别来产生多个级别
关于algorithm - 在递归算法和事件驱动的消费者之间进行协调的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22760943/
我想在包含点的主要方法中创建一个数组像 p={(3,8),(2,8)}与这个类 public class Point { private float x,y; public Point
在Elasticsearch中,建议将摄取节点设置为专用节点吗?我打算在k8s集群上运行Elasticsearch,并允许将提取容器安排在也运行其他Java服务容器的工作程序节点上。这是用于生产的良好
我最初的想法是使用管道来协调和控制多个C应用程序,并以shell脚本作为执行程序。假设一个 C 应用程序“A”执行 X,另一个 C 应用程序“B”执行 Y。shell 脚本通过 A 和 B 的 IPC
我在 json 文件中收集了推文集合。我想对它们进行操作,例如根据每个数据条目的时间和坐标对推文进行分组。目前,对于对象坐标,我将它们放在列表数据类型中。与时间和日期类似。所以我已经成功地解析了它们,
我有一个网页,用户应该可以在任何地方输入并跟踪他们的输入。一个问题是 firefox 中的斜线键“/”是打开搜索的快捷方式。这对我来说是不可取的。我还没有找到一种方法来捕获搜索功能并且仍然将输入添加到
我正在尝试使用 d3.dispatch 协调多个 View /控件和 Dispatching Events block 来指导我。然而,我遇到了概念上的障碍。考虑以下 View /控件: 国家/地区下
我在一台计算机上使用 Kaldi 工具集进行语音识别,但我无权修改 /var/kaldi 中的安装内容。该目录包含一个脚本文件夹,作为使用示例提供,这些脚本也彼此紧密链接。 结构如下,数据集mydat
在 C 中,“数组语法”只是指针语法的语法糖。那是a[4] 转换为 *(a+4)。 但这并不总是正确的。 当然下面是荒谬的, int a[4] = {1,2,3,4}; int *(a+4) =
我正在寻找一种方法来协调来自 3 个不同来源的元素。我已经将元素简化为只有一个键(字符串)和版本(长)。 列表是同时获得的(2 个来自单独的数据库查询,1 个来自另一个系统上的内存缓存)。 对于我的最
我开始了解 DDD,并担心从持久性中检索实体对象然后在 UI 的 View 模型中重构它们的性能影响。 假设我有两个聚合根: Person Orders ------ ------
我将 jQuery Flotchart 组件打包为 React 组件,每当组件属性发生更改时,我都需要调用图表实例的 plot 方法。 我最终得到的是 shouldComponentUpdate 钩子
如何在.plist中存储省份、城市和坐标信息?这些信息应该随我的应用程序一起提供。我尝试过以下格式,但不起作用。有没有其他方法可以替代plist?因为plist不利于查询。 ProvinceN
我一直在玩弄 SpriteKit,因为我想在一年内制作一款游戏,但最近我遇到了一些奇怪形式的减速带。 这就是问题所在。 我已经创建了一个常规的 SpriteKit 项目并更改了一些默认代码。我在位置
我有两个数组,在我的 C#/.NET Windows Forms 应用程序中使用 ChartDirector( http://www.advsofteng.com/product.html ) 将它们
我正在查看 article on wikipdia对于这个算法,我看到了两个看似矛盾的说法: "it also gives a deterministic way to check that the
我正在尝试将多个 CABasicAnimations 与 AVAudioPlayer 同步。我遇到的问题是 CABasicAnimation 在安排动画时使用 CACurrentMediaTime()
我们的项目正在使用 gitflow 详情 here我的问题是 QA 如何融入其中。 假设我有一个 master 分支和一个 hotfix 分支。一旦修补程序完成,我相信 QA 应该在修补程序发布时完成
有什么方法可以设置默认的 System.Web.Optimization.ScriptBundle 来生成 source maps对于捆绑和缩小的文件?除了必须在每次构建之前预先生成包和源映射之外,是
有什么方法可以设置默认的 System.Web.Optimization.ScriptBundle 来生成 source maps对于捆绑和缩小的文件?除了必须在每次构建之前预先生成包和源映射之外,是
更新到 Git 2.28 后,我意识到 conditional includes .但是,我无法找到一种方法来为 master(main) 设置不同的 pull reconciliation 选项,而
我是一名优秀的程序员,十分优秀!