`
coconut_zhang
  • 浏览: 541665 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

Java 笛卡尔积算法的简单实现

    博客分类:
  • java
 
阅读更多

 笛卡尔积算法的Java实现:

(1)循环内,每次只有一列向下移一个单元格,就是CounterIndex指向的那列。
(2)如果该列到尾部了,则这列index重置为0,而CounterIndex则指向前一列,相当于进位,把前列的index加一。
(3)最后,由生成的行数来控制退出循环。

public class Test {

	private static String[] aa = { "aa1", "aa2" };
	private static String[] bb = { "bb1", "bb2", "bb3" };
	private static String[] cc = { "cc1", "cc2", "cc3", "cc4" };
	private static String[][] xyz = { aa, bb, cc };
	private static int counterIndex = xyz.length - 1;
	private static int[] counter = { 0, 0, 0 };

	public static void main(String[] args) throws Exception {

		for (int i = 0; i < aa.length * bb.length * cc.length; i++) {
			System.out.print(aa[counter[0]]);
			System.out.print("\t");
			System.out.print(bb[counter[1]]);
			System.out.print("\t");
			System.out.print(cc[counter[2]]);
			System.out.println();

			handle();
		}
	}

	public static void handle() {
		counter[counterIndex]++;
		if (counter[counterIndex] >= xyz[counterIndex].length) {
			counter[counterIndex] = 0;
			counterIndex--;
			if (counterIndex >= 0) {
				handle();
			}
			counterIndex = xyz.length - 1;
		}
	}

}


输出共2*3*4=24行:
aa1 bb1 cc1
aa1 bb1 cc2
aa1 bb1 cc3
aa1 bb1 cc4
aa1 bb2 cc1
aa1 bb2 cc2
aa1 bb2 cc3
aa1 bb2 cc4
aa1 bb3 cc1
aa1 bb3 cc2
aa1 bb3 cc3
aa1 bb3 cc4
aa2 bb1 cc1
aa2 bb1 cc2
aa2 bb1 cc3
aa2 bb1 cc4
aa2 bb2 cc1
aa2 bb2 cc2
aa2 bb2 cc3
aa2 bb2 cc4
aa2 bb3 cc1
aa2 bb3 cc2
aa2 bb3 cc3
aa2 bb3 cc4

-------------------------------------------------------------------------------------------------------------------------------

最近碰到了一个笛卡尔积的算法要求,比如传递过来的参数是"1,3,6,7==4,5,8,9==3,4==43,45,8,9==35,4",则返回的是一个list,如[1,4,3,43,35][1,4,3,43,4][1,4,3,45,35]……,该list包含是4*4*2*4*2=256个元素,现在的思路是这样的:

 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DescartesTest {

    /**
     * 获取N个集合的笛卡尔积
     *
     * 说明:假如传入的字符串为:"1,2,3==5,6==7,8"
     *       转换成字符串数组为:[[1, 2, 3], [5, 6], [7, 8]]
     *       a=[1, 2, 3]
     *       b=[5, 6]
     *       c=[7, 8]
     *       其大小分别为:a_length=3,b_length=2,c_length=2,
     *       目标list的总大小为:totalSize=3*2*2 = 12
     *       对每个子集a,b,c,进行循环次数=总记录数/(元素个数*后续集合的笛卡尔积个数)
     *       对a中的每个元素循环次数=总记录数/(元素个数*后续集合的笛卡尔积个数)=12/(3*4)=1次,每个元素每次循环打印次数:后续集合的笛卡尔积个数=2*2个
     *       对b中的每个元素循环次数=总记录数/(元素个数*后续集合的笛卡尔积个数)=12/(2*2)=3次,每个元素每次循环打印次数:后续集合的笛卡尔积个数=2个
     *       对c中的每个元素循环次数=总记录数/(元素个数*后续集合的笛卡尔积个数)=12/(2*1)=6次,每个元素每次循环打印次数:后续集合的笛卡尔积个数=1个
     *     
     *      运行结果:
     *      [[1, 2, 3], [5, 6], [7, 8]]
            1,5,7,
            1,5,8,
            1,6,7,
            1,6,8,
            2,5,7,
            2,5,8,
            2,6,7,
            2,6,8,
            3,5,7,
            3,5,8,
            3,6,7,
            3,6,8]
           
                               从结果中可以看到:
            a中的每个元素每个元素循环1次,每次打印4个
            b中的每个元素每个元素循环3次,每次打印2个
            c中的每个元素每个元素循环6次,每次打印1个
           
     *
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String str ="1,3,6,7==4,5,8,9==3,4==43,45,8,9==35,4";
        List<String> result = descartes(str);
        System.out.println(result);

    }

    @SuppressWarnings("rawtypes")
    public static List<String> descartes(String str) {
        String[] list = str.split("==");
        List<List> strs = new ArrayList<List>();
        for(int i=0;i<list.length;i++){
        strs.add(Arrays.asList(list[i].split(",")));
        }
        System.out.println(strs);
        int total = 1;
        for(int i=0;i<strs.size();i++){
            total*=strs.get(i).size();
        }
        String[] mysesult = new String[total];
        int now = 1;
        //每个元素每次循环打印个数
        int itemLoopNum = 1;
        //每个元素循环的总次数
        int loopPerItem =1;
        for(int i=0;i<strs.size();i++){
            List temp = strs.get(i);
            now = now*temp.size();
            //目标数组的索引值
            int index=0;
            int currentSize = temp.size();
            itemLoopNum = total/now;
            loopPerItem = total/(itemLoopNum*currentSize);
            int myindex = 0;
            for(int j=0;j<temp.size();j++){

                //每个元素循环的总次数
                for(int k=0;k<loopPerItem;k++){
                    if(myindex==temp.size())
                        myindex=0;
                    //每个元素每次循环打印个数
                    for(int m=0;m<itemLoopNum;m++){
                        mysesult[index]=(mysesult[index]==null?"":mysesult[index]+",")+((String)temp.get(myindex));
                        index++;
                    }
                    myindex++;
                   
                }
            }
        }
        return Arrays.asList(mysesult);
    }

}

 

-------------------------------------------------------------------------------------------------------------------------------

递归:

public static void fn(List<String[]> list,String[] arr,String str){
        //迭代list
  List<String> li = new ArrayList<String>();
        for(int i=0;i<list.size();i++){
            //取得当前的数组
            if(i==list.indexOf(arr)){
                //迭代数组
             System.out.println(arr.length);
                for(String st : arr){
                    st = str + st;
                    
                    if(i<list.size()-1){
                        fn(list,list.get(i+1),st);
                    }else if(i==list.size()-1){
                      li.add(st);
                    }
                }
            }
        }
       
        for(int i = 0 ; i < li.size();i++ )
        {
         System.out.println(li.get(i));
        }
 }

  • 大小: 16.8 KB
分享到:
评论
1 楼 yujiaao 2017-08-25  
fn 函数循环是没有必要的啊,可以改成


  protected static List<String> fn(List<Object[]> list, Object[] arr, String result, String separator) {
        //迭代list
        List<String> li = new ArrayList<String>();
        //取得当前的数组
        int i = list.indexOf(arr);
        //迭代数组
        for (Object st : arr) {
            if (StringUtils.isNotBlank(result)) {
                st = result + separator + st;
            }

            if (i < list.size() - 1) {
                li.addAll(fn(list, list.get(i + 1), st.toString(), separator));
            } else if (i == list.size() - 1) {
                li.add(st.toString());
            }
        }

        return li;
    }

相关推荐

    Java笛卡尔积算法原理与实现方法详解

    Java笛卡尔积算法原理与实现方法详解 Java笛卡尔积算法是一种重要的数据处理技术,广泛应用于数据分析、机器学习、数据挖掘等领域。下面将详细介绍Java笛卡尔积算法的原理与实现方法。 一、笛卡尔积算法原理 ...

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

    Java基于递归和循环两种方式实现未知维度集合的笛卡尔积算法示例 Java语言中实现未知维度集合的笛卡尔积算法是数据处理和分析中的一个重要问题。本文将主要介绍Java基于递归和循环两种方式实现未知维度集合的笛卡尔...

    javascript笛卡尔积算法实现方法

    JavaScript 笛卡尔积算法是一种用于计算多个集合所有可能的组合的方法。在数学中,笛卡尔积是通过将每个集合中的元素与其他集合的所有元素配对来形成的。在编程中,这通常用于生成所有可能的选项组合,例如在创建...

    Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例

    说明:本人前段时间遇到的求n个数组的所有排列组合的问题,发现笛卡尔积算法可以解决,但是网上搜索的只有Java版本的实现,于是自己试着用python实现,由于新手代码不太规范。 代码:本人封装了一个类Cartesian...

    descartes-sku.js:笛卡尔算法,用于生成商品sku

    笛卡尔乘积算法笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(笛卡尔积),又称直积,表示为X×Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。功能基于笛卡尔乘积算法基础上编写的一个...

    笛卡尔心形

    接下来,我们将在Java中实现这个算法。首先,我们需要一个可以绘制图形的环境,比如Java的`java.awt.Graphics`类或者JavaFX的`Canvas`。这里我们以`Graphics`为例: ```java import javax.swing.JFrame; import ...

    A-star算法实验报告(附源码java)

    A* 算法是一种高效的路径搜索算法,广泛应用于游戏开发、地图导航、机器人路径规划等领域。...通过Java编程实现,展示了算法的基本思想和核心流程,同时也体现了启发式搜索在优化路径搜索效率上的巨大优势。

    sgp4算法(tle卫星轨道数据转成笛卡尔系坐标)

    将tle卫星轨道数据转换为笛卡尔系坐标是SGP4算法应用的关键步骤。笛卡尔坐标系统是一个直角坐标系统,用X、Y、Z三个轴表示卫星相对于地球中心的位置。在地球中心固定坐标系(ECF)中,X轴指向春分点,Y轴与赤道面...

    笛卡尔心形图

    java写的笛卡尔心形图,里边用了笛卡尔算法,代码不多..

    从n个数组中取出所有排列组合(Java实现)

    以下是一个简单的Java实现思路: 1. 定义一个递归函数,接收当前组合的索引位置、当前组合数组、未处理的数组列表作为参数。 2. 如果所有元素都被选中(即组合完成),将当前组合添加到结果集合中。 3. 对于未处理...

    java 和 c# 不同的7个方法 实现 ABCD 全排列

    在编程领域,全排列是算法设计中的一个常见问题,它涉及到如何生成一组特定元素的所有可能排列方式。在Java和C#这两个广泛使用的编程语言中,有许多不同的方法可以实现全排列。接下来,我们将深入探讨这两种语言中...

    计算机图形学算法的java代码

    Java作为一种广泛使用的编程语言,因其跨平台的特性,常常被用来实现计算机图形学的算法。 本压缩包包含的Java代码实现近20个计算机图形学的实例,这为我们提供了深入了解和学习计算机图形学算法的宝贵资源。以下是...

    基于遗传算法的排课系统

    排课系统的数学模型是将所有课程、班级、教师和教室看作四个集合,通过构建时间教室对的笛卡尔积来表示所有可能的课程安排。排课问题的求解就是找到满足所有约束条件且成本最低(或最高教学效果)的课表配置。通过...

    barsky梁友栋算法

    在"Barsky.c"这个文件中,很可能包含了实现上述算法的C语言代码。通过阅读和理解这段代码,我们可以学习如何在实际项目中应用这个算法,从而处理二维图形的裁剪问题。代码通常会定义线段的数据结构,提供裁剪函数,...

    七参数坐标转换Java语言代码

    在IT行业中,坐标转换是一项重要的任务,特别是在地理信息系统(GIS)领域。...通过深入理解这些代码,不仅可以学习到坐标转换的原理,还能提升Java编程技能,尤其是处理复杂算法和数值计算的能力。

    全面的算法代码仓库全面的算法代码仓库

    使用ISAP算法进行二分图匹配 Bigraph-Matching(Improved-Shortest-Augmenting-Path) 普通的二叉搜索树 Binary-Search-Tree 广度优先搜索 Breadth-First-Search 冒泡排序 Bubble-Sort 桶排序 Bucket-Sort 笛卡尔树 ...

    简易画图板程序java

    【简易画图板程序java】是一个基于Java编程语言实现的简单图形绘制软件,它涵盖了图形学的基本概念和技术,为用户提供了一个交互式的平台,可以进行基本的图形绘制操作。这个程序的核心功能包括画直线、绘制圆以及对...

    java contour

    在Java编程环境中,实现等值线绘制需要掌握特定的算法和库。本篇将深入探讨Java中实现等值线绘制的关键知识点,包括算法原理、相关库的使用以及代码实现。 1. **等值线算法**: - **格网化数据**:等值线绘制的第...

    WGS-84大地坐标转北京-54坐标java源代码;七参数、四参数;坐标转换

    7. **源代码**:提供的Java源代码如`Co_transformation.java`, `Test.java`, `Test_7cansu.java`, `Xiamen_cotrans.java`等,应该是实现了上述坐标转换算法的程序。`BLH.java`, `XYZ.java`, `Pxyz.java`可能是处理...

    JAVA 阿基米德螺线 图形化界面 计算机 编程

    在实现这个实验时,可能会用到以下关键的Java类和方法: 1. `javax.swing.JFrame`:主窗口类,用于创建应用的主窗口。 2. `javax.swing.JPanel`:作为自定义绘图组件的基础,继承它并重写`paintComponent`方法。 3....

Global site tag (gtag.js) - Google Analytics