以程序员编程的角度去理解笛卡尔积

数据库 waitig 624℃ 百度已收录 0评论

以程序员编程的角度去理解笛卡尔积

笛卡尔积其实就是一种线性代数关系。 学过线性代数的人都知道,笛卡尔乘积通俗的说,就是两个集合中的每一个成员,都与对方集合中的任意一个成员有关联。

假设 A 表 数据:
这里写图片描述
假设B表数据:
这里写图片描述
那么A,B表的笛卡尔积为:
这里写图片描述
那么对于程序员来说怎么用程序员的角度去理解笛卡尔积呢?
其实笛卡尔积就相当与两个循环,首先循环A,再在A循环内循环B。所叠加的结果。我们以Java语言来做演示,用List,Map来模拟表数据结构。一个Map对应一行数据,List代表表数据集合。


import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class ABTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //表A
        List<Map<String,Object>> A = new ArrayList<Map<String,Object>>();
        //表B
        List<Map<String,Object>> B = new ArrayList<Map<String,Object>>();
        //模拟笛卡尔乘积表
        List<Map<String,Object>> AB = new ArrayList<Map<String,Object>>();
        //初始化A,B数据
        initList(A,"A");
        initList(B,"B");

        //模拟笛卡尔积
        int a_size = A.size();
        int b_size = B.size();
        Map<String,Object> row = null;
        for(int a = 0; a < a_size; a++)
        {
            for(int b = 0; b < b_size; b++)
            {
                //if(B.get(b).get(key) == A.get(a).get(key)){//此处表示过滤条件,加上过滤条件就不是笛卡尔积了,
                //但是这里可以模拟Where条件

                //使用TreeMap使得Map中的Key值按一定的顺序排序
                row = new TreeMap<String, Object>();
                row.putAll(B.get(b));
                row.putAll(A.get(a));
                AB.add(row);
                //}
            }
        }
        System.err.println(AB);
    }

     static void initList(List<Map<String,Object>>list,String listName)
     {
            Map<String,Object> row = null;
            int limit = ("A".equalsIgnoreCase(listName) ? 4 : 3);
            int num = 0;
            for(int i =1; i < limit; i++)
            {
                row = new Hashtable<String, Object>();
                num = (i-1)*3;
                if(i >= 2 && "A".equalsIgnoreCase(listName))
                {
                    num = (i-1)*3-1;
                    row.put(listName+"1",listName+(num+1));
                }
                else if(i == 1 && "B".equalsIgnoreCase(listName))
                {
                    row.put(listName+i,"A1");
                }
                else
                {
                    row.put(listName+"1",listName+(num+1));
                }
                row.put(listName+"2",listName+(num+2));
                row.put(listName+"3",listName+(num+3));
                list.add(row);
            }
     }
}

运行结果:

[
  {A1=A1, A2=A2, A3=A3, B1=A1, B2=B2, B3=B3}, 
  {A1=A1, A2=A2, A3=A3, B1=B4, B2=B5, B3=B6}, 
  {A1=A3, A2=A4, A3=A5, B1=A1, B2=B2, B3=B3}, 
  {A1=A3, A2=A4, A3=A5, B1=B4, B2=B5, B3=B6}, 
  {A1=A6, A2=A7, A3=A8, B1=A1, B2=B2, B3=B3}, 
  {A1=A6, A2=A7, A3=A8, B1=B4, B2=B5, B3=B6}
]

比对结果是一致的(注:举例中没有使用ID是因为在A,B中都有ID字段,放到Map中会冲突,可能引起一些误解,所以演示案例将ID移除)。

使用过滤就是在以上代码的if语句中添加判断语句。

其他SQL查询可自行类比。


本文由【waitig】发表在等英博客
本文固定链接:以程序员编程的角度去理解笛卡尔积
欢迎关注本站官方公众号,每日都有干货分享!
等英博客官方公众号
点赞 (0)分享 (0)