一六一、了解笛卡尔积定义和运算规则&go实现计算多个集合的笛卡尔积

笛卡尔积是数学中两个集合之间的运算,其结果是所有可能的有序对组合。形式上,给定两个集合 ( A ) 和 ( B ),它们的笛卡尔积 ( A \times B ) 定义为:

A×B={(a,b)∣a∈A,b∈B}

即,笛卡尔积中的元素是所有可能的由 ( A ) 中的元素和 ( B ) 中的元素组成的有序对。

运算规则

  1. 有序性:笛卡尔积中的元素是有序对,这意味着对 ((a, b)) 和 ((b, a)) 而言,如果 ( a \neq b ),那么 ((a, b) \neq (b, a))。
  2. 元素唯一性:每个有序对的元素来自各自的集合,不重复计算。
  3. 空集情况:若 ( A ) 或 ( B ) 中有一个为空集,则 ( A \times B = \emptyset )。

例子

例子1:
设 ( A = {1, 2} ) 和 ( B = {a, b, c} )。
那么,笛卡尔积 ( A \times B ) 为:

A×B={(1,a),(1,b),(1,c),(2,a),(2,b),(2,c)}

例子2:
设 ( A = {x, y} ) 和 ( B = \emptyset )。
那么,笛卡尔积 ( A \times B ) 为:

A×B=∅

因为 ( B ) 是空集,所以没有与 ( A ) 中元素配对的元素,结果也是空集。

例子3:
设 ( A = {1} ) 和 ( B = {2, 3} )。
那么,笛卡尔积 ( A \times B ) 为:

A×B={(1,2),(1,3)}

这些例子展示了笛卡尔积的基本计算方式和结果的形式。

go实现计算多个集合的笛卡尔积

示例调用
package main

import (
	"fmt"
)

func Cartesian(sets ...[]any) [][]any {
	length := func(i int) int { return len(sets[i]) }
	nextIndex := func(ix []int, length func(idx int) int) {
		for i := len(ix) - 1; i >= 0; i-- {
			ix[i]++
			if i == 0 || ix[i] < length(i) {
				return
			}
			ix[i] = 0
		}
	}
	var result [][]any
	for ix := make([]int, len(sets)); ix[0] < length(0); nextIndex(ix, length) {
		var r []any
		for i, j := range ix {
			r = append(r, sets[i][j])
		}
		result = append(result, r)
	}
	return result
}

func main() {
	set1 := []any{1, 2}
	set2 := []any{"a", "b", "c"}
	set3 := []any{true, false}

	result := Cartesian(set1, set2, set3)

	for _, combo := range result {
		fmt.Println(combo)
	}
}

输出结果

[1 a true]
[1 a false]
[1 b true]
[1 b false]
[1 c true]
[1 c false]
[2 a true]
[2 a false]
[2 b true]
[2 b false]
[2 c true]
[2 c false]

在这个例子中,Cartesian 函数计算了集合 {1, 2}{"a", "b", "c"}{true, false} 的笛卡尔积,返回了所有可能的组合。

代码解释
  1. 参数和返回值

    • sets ...[]any:可变参数,表示多个集合,每个集合是一个任意类型的切片。
    • 返回值 [][]any:返回一个二维切片,每个元素是一个有序对的组合。
  2. 内部函数 length

    • 定义为 func(i int) int { return len(sets[i]) },用于获取第 i 个集合的长度。
  3. 内部函数 nextIndex

    • 接受一个索引数组 ix 和一个获取长度的函数 length
    • 它的作用是将索引数组 ix 的元素逐一增加,以生成下一个组合。
    • 如果当前索引超出集合长度,则重置当前索引并增加前一个集合的索引。
  4. 主循环

    • 初始化索引数组 ix,其长度与输入的集合数量相同,初始值为 [0, 0, ..., 0]
    • 使用 for 循环遍历所有可能的组合,直到第一个集合的所有元素都遍历完为止。
    • 内循环 for i, j := range ix 用于构建当前组合 r
    • 将当前组合 r 添加到 result 切片中。
  5. 返回结果

    • 返回包含所有可能组合的 result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值