笛卡尔积
在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。
假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
编程里笛卡尓积常用于生成商品的各种规格。
实现#
PHP#
<?php
$color = array('红', '黄', '黑');
$size = array(39, 40, 41);
$local = array('男', '女');
echo "<pre>";
echo json_encode(combineDika($local, $color, $size));
/**
* 所有数组的笛卡尔积
*
* @param unknown_type $data
*/
function combineDika() {
$data = func_get_args();
$cnt = count($data);
$result = array();
foreach($data[0] as $item) {
$result[] = array($item); //取出第一个数组里的各个元素组成新的二元数组,示例: array('红', '黄', '黑') 转为 array(array('红'),array('黄'), array('黑'))
}
for($i = 1; $i < $cnt; $i++) {
//追加后续数组的元素到第一个数组里
$result = combineArray($result,$data[$i]);
}
return $result;
}
/**
* 两个数组的笛卡尔积
*
* @param unknown_type $arr1 ,示例: array(array('红'),array('黄'), array('黑'))
* @param unknown_type $arr2
*/
function combineArray($arr1,$arr2) {
$result = array();
foreach ($arr1 as $item1) {
foreach ($arr2 as $item2) {
$temp = $item1; // $item1是数组
$temp[] = $item2; //追加上元素$item2
$result[] = $temp; //组成新数组
}
}
return $result;
}
?>
结果:
[
["男", "红", 39],
["男", "红", 40],
["男", "红", 41],
["男", "黄", 39],
["男", "黄", 40],
["男", "黄", 41],
["男", "黑", 39],
["男", "黑", 40],
["男", "黑", 41],
["女", "红", 39],
["女", "红", 40],
["女", "红", 41],
["女", "黄", 39],
["女", "黄", 40],
["女", "黄", 41],
["女", "黑", 39],
["女", "黑", 40],
["女", "黑", 41]
]
JavaScript#
这里可根据给的对象或者数组生成笛卡尔积
//笛卡儿积组合
function descartes(list)
{
//parent上一级索引;count指针计数
var point = {};
var result = [];
var pIndex = null;
var tempCount = 0;
var temp = [];
//根据参数列生成指针对象
for(var index in list)
{
if(typeof list[index] == 'object')
{
point[index] = {'parent':pIndex,'count':0}
pIndex = index;
}
}
//单维度数据结构直接返回
if(pIndex == null)
{
return list;
}
//动态生成笛卡尔积
while(true)
{
for(var index in list)
{
tempCount = point[index]['count'];
temp.push(list[index][tempCount]);
}
//压入结果数组
result.push(temp);
temp = [];
//检查指针最大值问题
while(true)
{
if(point[index]['count']+1 >= list[index].length)
{
point[index]['count'] = 0;
pIndex = point[index]['parent'];
if(pIndex == null)
{
return result;
}
//赋值parent进行再次检查
index = pIndex;
}
else
{
point[index]['count']++;
break;
}
}
}
}
示例:
var list = [['男','女'], ['红', '黄', '黑'], [39, 40, 41]];
var res = descartes(list);
(本文完)
本文优先在公众号"飞鸿影的博客(fhyblog)"发布,欢迎关注公众号及时获取最新文章推送!
本文优先在公众号"飞鸿影的博客(fhyblog)"发布,欢迎关注公众号及时获取最新文章推送!

作者:飞鸿影
出处:http://52fhy.cnblogs.com/
版权申明:没有标明转载或特殊申明均为作者原创。本文采用以下协议进行授权,自由转载 - 非商用 - 非衍生 - 保持署名 | Creative Commons BY-NC-ND 3.0,转载请注明作者及出处。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了