Golang Go语言中怎么用搞一个 [多维的笛卡尔积] 呀?

Golang Go语言中怎么用搞一个 [多维的笛卡尔积] 呀?

有这么个需求, 给一组维度, 维度的数量不固定, 各个维度的取值数目也不一定。 类似

di: 0, 1, 2 
dj: 0, 1
dk: 0, 1, 2, 3, 4
...

怎么取得这么一组给定不定长维度下值的组合?

# example
package main

import “fmt”

var ( di = []int{0, 1, 2} dj = []int{0, 1} dk = []int{0, 1, 2, 3, 4} )

func main() { getResult(di, dj, dk) }

func getResult(di, dj, dk []int) { for _, i := range di { for _, j := range dj { for _, k := range dk { fmt.Printf("[%d, %d, %d] \t", i, j, k) } } } }

# result
[0, 0, 0] 	[0, 0, 1] 	[0, 0, 2] 	[0, 0, 3] 	[0, 0, 4] 	[0, 1, 0] 	[0, 1, 1] 	[0, 1, 2] 	[0, 1, 3] 	[0, 1, 4] 	[1, 0, 0] 	[1, 0, 1] 	[1, 0, 2] 	[1, 0, 3] 	[1, 0, 4] 	[1, 1, 0] 	[1, 1, 1] 	[1, 1, 2] 	[1, 1, 3] 	[1, 1, 4] 	[2, 0, 0] 	[2, 0, 1] 	[2, 0, 2] 	[2, 0, 3] 	[2, 0, 4] 	[2, 1, 0] 	[2, 1, 1] 	[2, 1, 2] 	[2, 1, 3] 	[2, 1, 4] 	

如果维度再增加, 还得手动加上一套for range。 有没有更好的解决方案?


更多关于Golang Go语言中怎么用搞一个 [多维的笛卡尔积] 呀?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

16 回复

和指定长度数组的全排列蛮像的,循环的层数是不确定的,只是取数字的方式不一样

更多关于Golang Go语言中怎么用搞一个 [多维的笛卡尔积] 呀?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是不是可以考虑用代码生成代码的思路?

递归

只写一层 for,自己判断跳出条件和累加策略

应该没有你这样写代码的。。。

for 有点多

不一定是最高效的办法:
go<br>package main<br><br>import "fmt"<br><br>var (<br> di = []int{0, 1, 2}<br> dj = []int{0, 1}<br> dk = []int{0, 1, 2, 3, 4}<br>)<br><br>func main() {<br> res := getResult(di, dj, dk)<br> for _, item := range res {<br> fmt.Println(item)<br> }<br>}<br><br>func getResult(d0 []int, d1 ...[]int) (res [][]int) {<br> if len(d1) == 0 {<br> res = make([][]int, 0, len(d0))<br> for _, d := range d0 {<br> res = append(res, []int{d})<br> }<br> return<br> }<br> sub := getResult(d1[0], d1[1:]...)<br> for _, item := range d0 {<br> for _, s := range sub {<br> c := []int{item}<br> c = append(c, s...)<br> res = append(res, c)<br> }<br> }<br> return<br>}<br>

哈哈哈看来 V2EX 的少年算法水平不行啊
这看起来是求全排列吗?
最基本的解决方案可以看基础的算法里的暴力破解,不剪枝
手机登的 V2EX 没法发代码……图片也不知道咋发

“”“
func main() {
input := [][]int{[]int{1, 2, 3, }, []int{5, 6, 7, 8}, []int{9, 10, 11, 12}}
res := make([][]int, 0)
rec := make([]int, 0)
helper(input, &res, &rec, 0)
fmt.Println(res)

}

func helper(input [][]int, res *[][]int, rec *[]int, index int) {
if index < len(input) {
for _, v := range input[index] {
*rec = append(*rec, v)
helper(input, res, rec, index+1)
*rec = (*rec)[:index]
}
return
}
tmp := make([]int, len(input))
copy(tmp, *rec)
*res = append(*res, tmp)
*rec = (*rec)[:index]
}

”""

基础的 DFS

java<br>class Demo {<br><br> public static void main(String[] args) {<br> new Demo().func();<br> }<br><br> public void func() {<br> List&lt;List&lt;Integer&gt;&gt; res = new ArrayList&lt;&gt;();<br> List&lt;List&lt;Integer&gt;&gt; sourceList = new ArrayList&lt;&gt;();<br> sourceList.add(Arrays.asList(0, 1, 2));<br> sourceList.add(Arrays.asList(0, 1));<br> sourceList.add(Arrays.asList(0, 1, 2, 3, 4));<br> dfs(sourceList, res, new ArrayList&lt;&gt;(), 0);<br> System.out.println(res);<br> }<br><br> public void dfs(List&lt;List&lt;Integer&gt;&gt; sourceList, List&lt;List&lt;Integer&gt;&gt; res, List&lt;Integer&gt; curList, int index) {<br> if (index == sourceList.size()) {<br> res.add(new ArrayList&lt;&gt;(curList));<br> } else {<br> List&lt;Integer&gt; source = sourceList.get(index);<br> for (Integer i : source) {<br> curList.add(i);<br> dfs(sourceList, res, curList, index + 1);<br> curList.remove(curList.size() - 1);<br> }<br><br> }<br> }<br><br>}<br>

builtin 的 append 方法就是用的 for 循环

康托展开。

在Go语言中实现多维笛卡尔积(Cartesian Product)通常涉及递归或迭代的方法,因为笛卡尔积本质上是多个集合间所有可能的组合。以下是一个简单的递归实现示例,假设你有多个切片,并希望计算它们的笛卡尔积:

package main

import (
	"fmt"
	"reflect"
)

// CartesianProduct 计算多个切片的笛卡尔积
func CartesianProduct(slices [][]interface{}) [][]interface{} {
	if len(slices) == 0 {
		return [][]interface{}{{}}
	}
	var result [][]interface{}
	for _, v := range slices[0] {
		for _, product := range CartesianProduct(slices[1:]) {
			result = append(result, append([]interface{}{v}, product...))
		}
	}
	return result
}

func main() {
	set1 := []interface{}{1, 2}
	set2 := []interface{}{'a', 'b'}
	set3 := []interface{}{true, false}
	result := CartesianProduct([][]interface{}{set1, set2, set3})
	for _, item := range result {
		fmt.Println(item)
	}
}

这个例子中,CartesianProduct 函数接收一个二维切片,其中每个子切片是一个集合。它递归地计算每个集合与剩余集合的笛卡尔积,并将结果合并。main 函数展示了如何使用这个函数来计算三个不同集合的笛卡尔积。这种方法可以扩展到任意数量的集合。

回到顶部