Java基于递归和循环两种方式实现未知维度集合的笛卡尔积算法示例

所属分类: 软件编程 / java 阅读数: 23
收藏 0 赞 0 分享

本文实例讲述了Java基于递归和循环两种方式实现未知维度集合的笛卡尔积。分享给大家供大家参考,具体如下:

什么是笛卡尔积?

在数学中,两个集合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的数量是未知的。下面的代码使用递归和循环两种方法实现未知维度集合的笛卡尔积:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * 循环和递归两种方式实现未知维度集合的笛卡尔积
 * Created on 2015-05-22
 * @author luweijie
 */
public class Descartes {
  /**
   * 递归实现dimValue中的笛卡尔积,结果放在result中
   * @param dimValue 原始数据
   * @param result 结果数据
   * @param layer dimValue的层数
   * @param curList 每次笛卡尔积的结果
   */
  private static void recursive (List<List<String>> dimValue, List<List<String>> result, int layer, List<String> curList) {
    if (layer < dimValue.size() - 1) {
      if (dimValue.get(layer).size() == 0) {
        recursive(dimValue, result, layer + 1, curList);
      } else {
        for (int i = 0; i < dimValue.get(layer).size(); i++) {
          List<String> list = new ArrayList<String>(curList);
          list.add(dimValue.get(layer).get(i));
          recursive(dimValue, result, layer + 1, list);
        }
      }
    } else if (layer == dimValue.size() - 1) {
      if (dimValue.get(layer).size() == 0) {
        result.add(curList);
      } else {
        for (int i = 0; i < dimValue.get(layer).size(); i++) {
          List<String> list = new ArrayList<String>(curList);
          list.add(dimValue.get(layer).get(i));
          result.add(list);
        }
      }
    }
  }
  /**
   * 循环实现dimValue中的笛卡尔积,结果放在result中
   * @param dimValue 原始数据
   * @param result 结果数据
   */
  private static void circulate (List<List<String>> dimValue, List<List<String>> result) {
    int total = 1;
    for (List<String> list : dimValue) {
      total *= list.size();
    }
    String[] myResult = new String[total];
    int itemLoopNum = 1;
    int loopPerItem = 1;
    int now = 1;
    for (List<String> list : dimValue) {
      now *= list.size();
      int index = 0;
      int currentSize = list.size();
      itemLoopNum = total / now;
      loopPerItem = total / (itemLoopNum * currentSize);
      int myIndex = 0;
      for (String string : list) {
        for (int i = 0; i < loopPerItem; i++) {
          if (myIndex == list.size()) {
            myIndex = 0;
          }
          for (int j = 0; j < itemLoopNum; j++) {
            myResult[index] = (myResult[index] == null? "" : myResult[index] + ",") + list.get(myIndex);
            index++;
          }
          myIndex++;
        }
      }
    }
    List<String> stringResult = Arrays.asList(myResult);
    for (String string : stringResult) {
      String[] stringArray = string.split(",");
      result.add(Arrays.asList(stringArray));
    }
  }
  /**
   * 程序入口
   * @param args
   */
  public static void main (String[] args) {
    List<String> list1 = new ArrayList<String>();
    list1.add("1");
    list1.add("2");
    List<String> list2 = new ArrayList<String>();
    list2.add("a");
    list2.add("b");
    List<String> list3 = new ArrayList<String>();
    list3.add("3");
    list3.add("4");
    list3.add("5");
    List<String> list4 = new ArrayList<String>();
    list4.add("c");
    list4.add("d");
    list4.add("e");
    List<List<String>> dimValue = new ArrayList<List<String>>();
    dimValue.add(list1);
    dimValue.add(list2);
    dimValue.add(list3);
    dimValue.add(list4);
    List<List<String>> recursiveResult = new ArrayList<List<String>>();
    // 递归实现笛卡尔积
    recursive(dimValue, recursiveResult, 0, new ArrayList<String>());
    System.out.println("递归实现笛卡尔乘积: 共 " + recursiveResult.size() + " 个结果");
    for (List<String> list : recursiveResult) {
      for (String string : list) {
        System.out.print(string + " ");
      }
      System.out.println();
    }
    List<List<String>> circulateResult = new ArrayList<List<String>>();
    circulate(dimValue, circulateResult);
    System.out.println("循环实现笛卡尔乘积: 共 " + circulateResult.size() + " 个结果");
    for (List<String> list : circulateResult) {
      for (String string : list) {
        System.out.print(string + " ");
      }
      System.out.println();
    }
  }
}

输出结果是:

递归实现笛卡尔乘积: 共 36 个结果
1 a 3 c
1 a 3 d
1 a 3 e
1 a 4 c
1 a 4 d
1 a 4 e
1 a 5 c
1 a 5 d
1 a 5 e
1 b 3 c
1 b 3 d
1 b 3 e
1 b 4 c
1 b 4 d
1 b 4 e
1 b 5 c
1 b 5 d
1 b 5 e
2 a 3 c
2 a 3 d
2 a 3 e
2 a 4 c
2 a 4 d
2 a 4 e
2 a 5 c
2 a 5 d
2 a 5 e
2 b 3 c
2 b 3 d
2 b 3 e
2 b 4 c
2 b 4 d
2 b 4 e
2 b 5 c
2 b 5 d
2 b 5 e
循环实现笛卡尔乘积: 共 36 个结果
1 a 3 c
1 a 3 d
1 a 3 e
1 a 4 c
1 a 4 d
1 a 4 e
1 a 5 c
1 a 5 d
1 a 5 e
1 b 3 c
1 b 3 d
1 b 3 e
1 b 4 c
1 b 4 d
1 b 4 e
1 b 5 c
1 b 5 d
1 b 5 e
2 a 3 c
2 a 3 d
2 a 3 e
2 a 4 c
2 a 4 d
2 a 4 e
2 a 5 c
2 a 5 d
2 a 5 e
2 b 3 c
2 b 3 d
2 b 3 e
2 b 4 c
2 b 4 d
2 b 4 e
2 b 5 c
2 b 5 d
2 b 5 e

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

更多精彩内容其他人还在看

Java简单实现农夫过河问题示例

这篇文章主要介绍了Java简单实现农夫过河问题,简单描述了农夫过河问题的概念、原理并结合简单实例形式分析了java解决农夫过河问题的相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

详解java中的四种代码块

这篇文章主要介绍了详解java中的四种代码块,具有一定借鉴价值,需要的朋友可以参考下。
收藏 0 赞 0 分享

Java 9中如何对IntegerCache进行修改详解

这篇文章主要给大家介绍了关于Java 9中如何对IntegerCache进行修改的相关资料,文中通过示例代码介绍的非常详细,对大家学习或使用java9具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧。
收藏 0 赞 0 分享

关于Java中你所不知道的Integer详解

这篇文章主要给大家介绍了关于Java中你所不知道的一些关于Integer的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

JavaWeb基于Session实现的用户登陆注销方法示例

为了安全起见,session常常用来保存用户的登录信息。那么服务器是怎么来实现的呢?下面这篇文章就来给大家介绍了关于JavaWeb基于Session实现的用户登陆注销的相关资料,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

详谈Java中net.sf.json包关于JSON与对象互转的坑

下面小编就为大家分享一篇Java中net.sf.json包关于JSON与对象互转的坑,具有很好的参考价值,希望对大家有所帮助
收藏 0 赞 0 分享

Springboot整合pagehelper分页功能

这篇文章主要为大家详细介绍了Springboot整合pagehelper分页功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解eclipse中Maven工程使用Tomcat7以上插件的方法

本篇文章主要介绍了详解eclipse中Maven工程使用Tomcat7以上插件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

堆排序实例(Java数组实现)

下面小编就为大家分享一篇使用Java数组实现堆排序的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Java基于递归和循环两种方式实现未知维度集合的笛卡尔积算法示例

这篇文章主要介绍了Java基于递归和循环两种方式实现未知维度集合的笛卡尔积算法,结合实例形式分析了Java使用递归与循环两种方式实现未知维度集合的笛卡尔积相关概念、原理与操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多