什么是计算笛卡尔积的好的非递归算法?
注意
这不是 REBOL 特定的问题。 您可以用任何语言回答。
背景
REBOL 语言支持创建特定于领域的语言,在 REBOL 中被称为“方言”用语< /em>. 我已经为列表推导创建了这样一种方言,REBOL 本身并不支持这种方言。
列表推导式需要良好的笛卡尔积算法。
问题
我使用元编程来解决这个问题,方法是动态创建然后执行一系列嵌套的 foreach
语句。 它工作得很漂亮。 但是,由于它是动态的,因此代码的可读性不太好。 REBOL 不太擅长递归。 它很快就会耗尽堆栈空间并崩溃。 所以递归的解决方案是不可能的。
总之,如果可能的话,我想用可读的、非递归的“内联”算法替换我的元编程。 解决方案可以是任何语言,只要我能在 REBOL 中重现它。 (我几乎可以阅读任何编程语言:C#、C、C++、Perl、Oz、Haskell、Erlang,等等。)
我应该强调的是,该算法需要支持任意数量的要“连接”的集合,因为列表理解可以涉及任意数量的集合。
Note
This is not a REBOL-specific question. You can answer it in any language.
Background
The REBOL language supports the creation of domain-specific languages known as "dialects" in REBOL parlance. I've created such a dialect for list comprehensions, which aren't natively supported in REBOL.
A good cartesian product algorithm is needed for list comprehensions.
The Problem
I've used meta-programming to solve this, by dynamically creating and then executing a sequence of nested foreach
statements. It works beautifully. However, because it's dynamic, the code is not very readable. REBOL doesn't do recursion well. It rapidly runs out of stack space and crashes. So a recursive solution is out of the question.
In sum, I want to replace my meta-programming with a readable, non-recursive, "inline" algorithm, if possible. The solution can be in any language, as long as I can reproduce it in REBOL. (I can read just about any programming language: C#, C, C++, Perl, Oz, Haskell, Erlang, whatever.)
I should stress that this algorithm needs to support an arbitrary number of sets to be "joined", since list comprehension can involve any number of sets.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
3 倍 速度更快,内存使用更少(回收更少)。
3 times Faster and less memory used (less recycles).
怎么样:
它会产生以下输出:
How about something like this:
Which produces the following output:
为了完整起见,以下是 Robert Gamble 的答案翻译成 REBOL:
For the sake of completeness, Here's Robert Gamble's answer translated into REBOL:
下面是一段 Java 代码,用于为具有任意数量元素的任意数量的集合生成笛卡尔积。
在此示例中,列表“ls”包含 4 个集合(ls1、ls2、ls3 和 ls4),如您所见,“ls”可以包含任意数量的具有任意数量元素的集合。
Here is a Java code to generate Cartesian product for arbitrary number of sets with arbitrary number of elements.
in this sample the list "ls" contains 4 sets (ls1,ls2,ls3 and ls4) as you can see "ls" can contain any number of sets with any number of elements.
输出
output
编辑:此解决方案不起作用。 罗伯特·甘布尔的解决方案是正确的。
我集思广益,想出了这个解决方案:(
我知道你们大多数人都不知道 REBOL,但它是一种相当可读的语言。)
此代码生成:(
第一次阅读上面的数字时,您可能会认为存在重复项。我做到了,但没有。)
有趣的是,这段代码使用了几乎与我的 数字根问题。
EDIT: This solution doesn't work. Robert Gamble's is the correct solution.
I brainstormed a bit and came up with this solution:
(I know most of you won't know REBOL, but it's a fairly readable language.)
This code produces:
(Upon first reading the numbers above, you may think there are duplicates. I did. But there aren't.)
Interestingly, this code uses almost the very same algorithm (1 + ((n - 1) % 9) that torpedoed my Digital Root question.