您的位置:首页 > 其它

递归和循环两种方式实现未知维度集合的笛卡尔积

2017-02-17 08:57 666 查看
什么是笛卡尔积?

在数学中,两个集合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)}。

如何用程序算法实现笛卡尔积?

如果编程前已知集合的数量,通过程序的多次循环即可得出笛卡尔积。但是如果编程前不知道集合的数量,如何得到笛卡尔积哪?比如集合表示List < List<String>> list;这个list在编程前list的数量是未知的。下面的代码使用递归和循环两种方法实现未知维度集合的笛卡尔积:

1 import java.util.ArrayList;
2 import java.util.Arrays;
3 import java.util.List;
4
5 /**
6  * 循环和递归两种方式实现未知维度集合的笛卡尔积
7  * Created on 2015-05-22
8  * @author luweijie
9  */
10 public class Descartes {
11
12     /**
13      * 递归实现dimValue中的笛卡尔积,结果放在result中
14      * @param dimValue 原始数据
15      * @param result 结果数据
16      * @param layer dimValue的层数
17      * @param curList 每次笛卡尔积的结果
18      */
19     private static void recursive (List<List<String>> dimValue, List<List<String>> result, int layer, List<String> curList) {
20         if (layer < dimValue.size() - 1) {
21             if (dimValue.get(layer).size() == 0) {
22                 recursive(dimValue, result, layer + 1, curList);
23             } else {
24                 for (int i = 0; i < dimValue.get(layer).size(); i++) {
25                     List<String> list = new ArrayList<String>(curList);
26                     list.add(dimValue.get(layer).get(i));
27                     recursive(dimValue, result, layer + 1, list);
28                 }
29             }
30         } else if (layer == dimValue.size() - 1) {
31             if (dimValue.get(layer).size() == 0) {
32                 result.add(curList);
33             } else {
34                 for (int i = 0; i < dimValue.get(layer).size(); i++) {
35                     List<String> list = new ArrayList<String>(curList);
36                     list.add(dimValue.get(layer).get(i));
37                     result.add(list);
38                 }
39             }
40         }
41     }
42
43     /**
44      * 循环实现dimValue中的笛卡尔积,结果放在result中
45      * @param dimValue 原始数据
46      * @param result 结果数据
47      */
48     private static void circulate (List<List<String>> dimValue, List<List<String>> result) {
49         int total = 1;
50         for (List<String> list : dimValue) {
51             total *= list.size();
52         }
53         String[] myResult = new String[total];
54
55         int itemLoopNum = 1;
56         int loopPerItem = 1;
57         int now = 1;
58         for (List<String> list : dimValue) {
59             now *= list.size();
60
61             int index = 0;
62             int currentSize = list.size();
63
64             itemLoopNum = total / now;
65             loopPerItem = total / (itemLoopNum * currentSize);
66             int myIndex = 0;
67
68             for (String string : list) {
69                 for (int i = 0; i < loopPerItem; i++) {
70                     if (myIndex == list.size()) {
71                         myIndex = 0;
72                     }
73
74                     for (int j = 0; j < itemLoopNum; j++) {
75                         myResult[index] = (myResult[index] == null? "" : myResult[index] + ",") + list.get(myIndex);
76                         index++;
77                     }
78                     myIndex++;
79                 }
80
81             }
82         }
83
84         List<String> stringResult = Arrays.asList(myResult);
85         for (String string : stringResult) {
86             String[] stringArray = string.split(",");
87             result.add(Arrays.asList(stringArray));
88         }
89     }
90
91     /**
92      * 程序入口
93      * @param args
94      */
95     public static void main (String[] args) {
96         List<String> list1 = new ArrayList<String>();
97         list1.add("1");
98         list1.add("2");
99
100         List<String> list2 = new ArrayList<String>();
101         list2.add("a");
102         list2.add("b");
103
104         List<String> list3 = new ArrayList<String>();
105         list3.add("3");
106         list3.add("4");
107         list3.add("5");
108
109         List<String> list4 = new ArrayList<String>();
110         list4.add("c");
111         list4.add("d");
112         list4.add("e");
113
114         List<List<String>> dimValue = new ArrayList<List<String>>();
115         dimValue.add(list1);
116         dimValue.add(list2);
117         dimValue.add(list3);
118         dimValue.add(list4);
119
120         List<List<String>> recursiveResult = new ArrayList<List<String>>();
121         // 递归实现笛卡尔积
122         recursive(dimValue, recursiveResult, 0, new ArrayList<String>());
123
124         System.out.println("递归实现笛卡尔乘积: 共 " + recursiveResult.size() + " 个结果");
125         for (List<String> list : recursiveResult) {
126             for (String string : list) {
127                 System.out.print(string + " ");
128             }
129             System.out.println();
130         }
131
132         List<List<String>> circulateResult = new ArrayList<List<String>>();
133         circulate(dimValue, circulateResult);
134         System.out.println("循环实现笛卡尔乘积: 共 " + circulateResult.size() + " 个结果");
135         for (List<String> list : circulateResult) {
136             for (String string : list) {
137                 System.out.print(string + " ");
138             }
139             System.out.println();
140         }
141     }
142 }

转载 http://blog.csdn.net/buptdavid/article/details/45918647[/code] 
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: