笛卡尔积 golang

定义

笛卡尔积一般表示为公式:X * Y, 主要描述两个集合中元素所有可能的组合。
例如集合 {1, 2}{x, y}其笛卡尔积为 [{1, x}, {1, y}, {2, x}, {2, y}]
结果集长度为len(X) * len(Y)

计算思路

假设需要计算三个集合 a * b * c的笛卡尔积,根据笛卡尔积公式。计算步骤可拆分如下:

  1. 计算 x = a * b
  2. 计算 x * c

例如 a = {"1", "2"}, b = {"a", "b"}, c = {"X", "Y"}

  1. 计算x = a * b, 结果为
[["1", "a"], ["1", "b"], ["2", "a"], ["2", "b"]]
  1. 计算 x * c, 结果为
[
	["1", "a", "X"], ["1", "a", "Y"],
	["1", "b", "X"], ["1", "b", "Y"],
	["2", "a", "X"], ["2", "a", "Y"],
	["2", "b", "X"], ["2", "b", "Y"],
]

计算任意多集合笛卡尔积时也是这个思路,按顺序分别计算相邻两个集合笛卡尔积(分治)

示例代码

var (
    a = []string{"a", "b"}
    b = []string{"1", "2"}
    c = []string{"X", "Y"}
    d = []string{"!", "@"}
)

a,b,c,d 4个集合,计算其笛卡尔积.

字符串版

package main

import "fmt"


var (
    a = []string{"a", "b"}
    b = []string{"1", "2"}
    c = []string{"X", "Y"}
    d = []string{"!", "@"}
)

func CartesianProductStr(strSets ...[]string) []string {
	orig := strSets[0] // 拆分第一个数组作为起始数组
	for _, other := range strSets[1:] {
		orig = merge(orig, other)
	}
	return orig
}

// merge 计算笛卡尔积
func merge(xs, ys []string) []string {
	item := make([]string, 0)
	for _, x := range xs {
		for _, y := range ys {
			item = append(item, x+y)
		}
	}
	return item
}

func main() {
	fmt.Println(CartesianProductStr(a, b, c, d))
}
// 输出结果:
// [a1X! a1X@ a1Y! a1Y@ a2X! a2X@ a2Y! a2Y@ b1X! b1X@ b1Y! b1Y@ b2X! b2X@ b2Y! b2Y@]

数组版

func CartesianProductArray(strSets ...[]string) [][]string {
	// 拆分第一个数组作为起始数组
	orig := make([][]string, len(strSets[0]))
	for idx, item := range strSets[0] {
		orig[idx] = []string{item}
	}

	for _, other := range strSets[1:] {
		orig = mergeArray(orig, other)
	}
	return orig
}

// merge 计算笛卡尔积
func mergeArray(xs [][]string, ys []string) [][]string {
	item := make([][]string, 0)
	for _, x := range xs {
		for _, y := range ys {
			item = append(item, append(x, y))
		}
	}
	return item
}

func main() {
	fmt.Println(CartesianProductArray(a, b, c, d))
}

// 输出结果:
// [[a 1 X @] [a 1 X @] [a 1 Y @] [a 1 Y @] [a 2 X @] [a 2 X @] [a 2 Y @] [a 2 Y @] [b 1 X @] [b 1 X @] [b 1 Y @] [b 1 Y @] [b 2 X @] [b 2 X @] [b 2 Y @] [b 2 Y @]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值