Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin中任意集合置换的逐步迭代_Kotlin_Permutation - Fatal编程技术网

Kotlin中任意集合置换的逐步迭代

Kotlin中任意集合置换的逐步迭代,kotlin,permutation,Kotlin,Permutation,我试图找到一种优雅的方法,逐步迭代任意数量集合或“桶”的所有可能排列。我需要分步进行,因为我正在处理大量可能的排列,并且已经耗尽了内存空间,试图将所有排列存储在内存中,然后删除无效的排列。取而代之的是,我试图一次一个地遍历每一个排列,并且只在有效的情况下将其存储在内存中的最终列表中,这样我就可以节省一些内存空间 我一直在尝试为此编写一个手动解决方案,但事实证明这有点困难-我不想确切知道我要处理多少列表/集合,所以我不能采用蛮力方法创建一系列嵌套for循环。为此创建自定义迭代器已被证明是其自身的一

我试图找到一种优雅的方法,逐步迭代任意数量集合或“桶”的所有可能排列。我需要分步进行,因为我正在处理大量可能的排列,并且已经耗尽了内存空间,试图将所有排列存储在内存中,然后删除无效的排列。取而代之的是,我试图一次一个地遍历每一个排列,并且只在有效的情况下将其存储在内存中的最终列表中,这样我就可以节省一些内存空间

我一直在尝试为此编写一个手动解决方案,但事实证明这有点困难-我不想确切知道我要处理多少列表/集合,所以我不能采用蛮力方法创建一系列嵌套for循环。为此创建自定义迭代器已被证明是其自身的一系列挑战

我希望有一些内置的方法或工具,我可以利用这一点,而无需重新发明轮子

下面是一个例子:假设我有两组字母:

[a, b, c], [n, c, a]
我的目标是从这两个“桶”中找到所有可能的字母排列,但只有那些集合中没有重复的字母(在现实世界的示例中,可能会有更复杂的需求,仅为了示例而使用这个简单的需求)。因此,所有可能的排列都是:

[a, n], [a, c], [a, a], 
[b, n], [b, c], [b, a],
[c, n], [c, c], [c, a].
现在我有了所有可能的排列,我想剔除那些不满足要求的排列:
[a,a]和[c,c]

我不想在事实发生后将它们剔除(并在临时内存中占用空间,否则它可能会被有效的组合填充),而是想在将其存储到内存之前检查每个创建的排列是否有效

Kotlin有没有什么东西可以让这更容易


编辑:我可以通过创建自己的“迭代器”类来实现这一点,该类逐步遍历每个排列,如果最终的集合已完全循环,则“冒泡”,以确保命中每个排列。如果有人对该解决方案感兴趣(可能效率稍低),我可以在这里发布该解决方案,但我仍然想知道是否有一种更简单的方法可以使用一些内置的Kotlin工具来实现这一点。

如果我理解这个问题,您需要的是集合的数量(“”通常指单个集合或其子集的所有元素的不同顺序。)

直接执行此操作很容易,使用方便:

这将返回一个,因此您可以执行任何筛选或其他所需的后处理,然后调用一个终端操作,例如after,以实际执行计算:

val result = (setOf('a', 'b', 'c') * setOf('n', 'c', 'a'))
            .filter{ it != 'a' to 'a' && it != 'c' to 'c' }
            .toList()
println(result)
// prints: [(a, n), (a, c), (b, n), (b, c), (b, a), (c, n), (c, a)]

(我对序列不是很有经验,所以我不能保证这是最有效的方法…

如果我理解这个问题,你要问的是集合的数量。(“”通常指单个集合的所有元素或其子集的不同顺序。)

直接执行此操作很容易,使用方便:

这将返回一个,因此您可以执行任何筛选或其他所需的后处理,然后调用一个终端操作,例如after,以实际执行计算:

val result = (setOf('a', 'b', 'c') * setOf('n', 'c', 'a'))
            .filter{ it != 'a' to 'a' && it != 'c' to 'c' }
            .toList()
println(result)
// prints: [(a, n), (a, c), (b, n), (b, c), (b, a), (c, n), (c, a)]

(我对序列没有太多经验,所以我不能保证这是最有效的方法…

你能为更多的集合提供一个例子吗?我不确定[a]、[b]、[c]应该是[a、b、c]还是[a、b]、[a、c]、[b、c]。所以每个“桶”将对应于最终集合中的一个索引。例如,如果我希望生成的集合包含5个元素,则需要从5个不同的“bucket”中选择一个元素.这有助于澄清吗?在你的例子中,如果我从3个独立的集合开始,这意味着结果将包含一个集合,每个集合有3个元素。因此,如果我从集合[a]、[b]、[c]开始,唯一可能的排列将是[a、b、c],你能为更多的集合提供一个例子吗?我不确定[a]、[b]、[c]应该是[a、b、c]还是[a、b],[a,c],[b,c]。因此,每个“bucket”都将对应于最终集合中的一个索引。例如,如果我希望生成的集合包含5个元素,则需要从5个不同的“bucket”中选择一个元素.这有助于澄清吗?在你的例子中,如果我从3个独立的集合开始,这意味着结果将包含一个集合,每个集合有3个元素。因此,如果我从集合[a],[b],[c]开始,唯一可能的排列将是[a,b,c]这是一个非常棒的解决方案!我认为序列位正是我一直在寻找的东西。我现在想弄清楚的一件事是,我如何扩展你的解决方案,以考虑任意数量的集合开始,也就是说,这将如何改变
乘以
运算符。因此,如果有3个集合需要求例如,我认为在当前的实现中,它将以类似((a,b),c)的形式结束。这可能通过将这些对展平成一个值列表来解决?是的,您可以将其扩展到多个集合,尽管这有点复杂。(我可能想更改
times()
函数获取两个序列,而不是创建它们;然后您可以使用
setA.asSequence()*setB.asSequence()*…
)但是,正如您所说,这将创建成对的序列……您可以使用列表代替,可能明智地使用
flatte()
,但随后您将创建许多临时对象,这正是我们想要避免的…好的一点-老实说,即使在最终实现了类似的东西之后,我意识到我正在为我的小项目处理的数据数量之多,最终有数亿个“有效”数据排列,所以这种中间过滤并没有我想象的那么有用…我想我必须将我的输入和结果集分割成单独的计算。但我很高兴我学到了一些关于序列的知识,不管怎样,你的解决方案是肯定的
val result = (setOf('a', 'b', 'c') * setOf('n', 'c', 'a'))
            .filter{ it != 'a' to 'a' && it != 'c' to 'c' }
            .toList()
println(result)
// prints: [(a, n), (a, c), (b, n), (b, c), (b, a), (c, n), (c, a)]