我想实现一个函数,它将返回set的笛卡尔积,重复给定的数字。例如
input: {a, b}, 2
output:
aa
ab
bb
ba
input: {a, b}, 3
aaa
aab
aba
baa
bab
bba
bbb
然而,我可以实现它的唯一方法是首先做2套(" ab"," ab)的cartesion产品,然后从套装的输出中添加相同的套装。这是伪代码:
function product(A, B):
result = []
for i in A:
for j in B:
result.append([i,j])
return result
function product1(chars, count):
result = product(chars, chars)
for i in range(2, count):
result = product(result, chars)
return result
我想要的是直接开始计算最后一组,而不计算它之前的所有组。这是否可行,也是一种可以给我类似结果的解决方案,但它不是可接受的笛卡儿产品。 我没有阅读大多数通用编程语言的问题,因此如果您需要发布代码,您可以使用您熟悉的任何语言进行编写。
答案 0 :(得分:1)
这是一个递归算法,它构建S ^ n而不构建S ^(n-1)“first”。想象一下无限的k-ary树,其中| S | = k。使用S的元素标记将任何父级连接到其k个子级的每个边。 S ^ m的元素可以被认为是从根开始的任何长度为m的路径。以这种思维方式,集合S ^ m是所有这些路径的集合。现在找到S ^ n的问题是枚举长度为n的所有路径的问题 - 我们可以通过从头到尾考虑边缘标签的顺序来命名路径。我们想要在没有首先枚举所有S ^(n-1)的情况下直接生成S ^ n,因此修改深度优先搜索以找到深度为n的所有节点似乎是合适的。这基本上是以下算法的工作原理:
// collection to hold generated output
members = []
// recursive function to explore product space
Products(set[1...n], length, current[1...m])
// if the product we're working on is of the
// desired length then record it and return
if m = length then
members.append(current)
return
// otherwise we add each possible value to the end
// and generate all products of the desired length
// with the new vector as a prefix
for i = 1 to n do
current.addLast(set[i])
Products(set, length, current)
currents.removeLast()
// reset the result collection and request the set be generated
members = []
Products([a, b], 3, [])
现在,广度优先方法的效率不亚于深度优先方法,如果你认为它与你正在做的事情没有什么不同。实际上,生成S ^ n的方法必须至少生成一次S ^(n-1),因为这可以在S ^ n的解中找到。