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


    什么是笛卡尔积?

    在数学中,两个集合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
  • 相关阅读:
    Java版本及历史简述
    ASCII、Unicode、UTF-8、UTF-16、GBK、GB2312、ANSI等编码方式简析
    同步(Synchronous)和异步(Asynchronous)方法的区别
    例10-12 *uva1637(概率dp)
    例10-11 uva11181
    例10-10 uva10491(简单概率)
    例10-9 uva1636简单概率问题
    全排列hash-康拓展开
    10-8 uva1262密码
    例10-6 uva1635(唯一分解定理)
  • 原文地址:https://www.cnblogs.com/cool5201314/p/6408277.html
Copyright © 2020-2023  润新知