您的位置:首页 > 编程语言 > Java开发

Java 排列组合和集合的交并差以及递归

2018-01-15 22:23 330 查看
最近正在做一个项目写递归写的不少,递归真的是Java中非常常见的,但是递归写的好不好也是取决于思维是否清晰。多思考自己的代码,尽量让代码变得优雅和可读性。

按照惯例推荐一首歌曲。我们的时光--赵雷

本文主要介绍三个方面的内容

1.Java中的排列组合

2.集合中的交并差(google Guava 和apache commons collectionsutil 都是可以的)

3.关于写递归时原则

mavne的依赖  

<Dependecy>

<groupId>org.raistlic.lib</groupId>

<artifactId>commons-core</artifactId>

<version>1.4</version>

</Dependecy>

import org.raistlic.common.permutation.Combination;
import org.raistlic.common.permutation.Permutation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* ${DESCRIPTION}
*
* @author mengxp
* @version 1.0
* @create 2018-01-15 21:05
**/
public class JoneTest {

public static final Logger CombineArithmeticLOG = LoggerFactory.getLogger(JoneTest.class);
public static final String ARITHMETIC_CONNECT_SPLIT = "\\$";
public static final String ARITHMETIC_CONNECT = "$";

/**
* 对集合中的元素进行全排列
* [1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
*/
public void testPermutationAll(){
Permutation<String> of = Permutation.of(Arrays.asList("1", "2", "3"));
for (List<String> list : of) {
System.out.println(list);
}
}

/**
* 对集合中的任取numberToPick个数进行全排列
*/
public void testPermutationOfDefine(){
int cout = 0;
for (List<Integer> list : Permutation.of(Arrays.asList(1, 2, 3, 4, 5), 3)) {
cout++;
System.out.println(list);
}
System.out.println(cout);
}

/**
* 取出集合中的任意个数 组合计算
*/
public void testCombinationOfDefine(){
for (List<Integer> list : Combination.of(Arrays.asList(1, 2, 3, 4, 5), 3))
System.out.println(list);
}

public static void main(String[] args) {
HashSet<String> result=new HashSet();
exeMain(true,2,Arrays.asList("a","b","c"),result);
System.out.println("xxxx");
}

/**
*
* @param isFlag        采用排列或者组合的方式
* @param combieCounter 子集合的组合方式
* @param sourece       数据源
* @param resultSets    返回的结果集
* @return  mengxp
*/
public static Set<String> exeMain(boolean isFlag, int combieCounter, List<String> sourece, Set<String> resultSets) {
if (sourece == null) {
CombineArithmeticLOG.error("sourece is null...");
return resultSets;
}
if (sourece != null || sourece.size() == 0) {
if (combieCounter > sourece.size()) {
CombineArithmeticLOG.error("combineCounter must be < source size...");
return resultSets;
}
}
if (isFlag) {//TODO 全排列
List<List<String>> pl = RankArithmetic.pl(sourece);
for (int i = 0; i < pl.size(); i++) {
select(combieCounter, pl.get(i), resultSets);
}
} else {
//TODO 全组合
select(combieCounter, sourece, resultSets);
}
return resultSets;
}

private static void select(int k, List<String> sources, Set<String> resultSet) {
String[] result = new String[k];
subselect(0, 1, result, k, sources, resultSet);
}

/**
* 递归算法
* @param head
* @param index
* @param r
* @param k
*/
private static void subselect(int head, int index, String[] r, int k, List<String> sources, Set<String> resultSet) {
for (int i = head; i < sources.size() + index - k; i++) {
if (index < k) {
r[index - 1] = sources.get(i);
subselect(i + 1, index + 1, r, k, sources, resultSet);
} else if (index == k) {
r[index - 1] = sources.get(i);
String content = "";
for (int j = 0; j < r.length; j++) {
String a = r[j];
content = content + ARITHMETIC_CONNECT + a;
}
content = content.replaceFirst(ARITHMETIC_CONNECT_SPLIT, "");
resultSet.add(content);
subselect(i + 1, index + 1, r, k, sources, resultSet);
} else {
return;
}
}
}

}


import java.util.LinkedList;
import java.util.List;

/**
* Created by mengxp on 2017/8/18.
*/
public class RankArithmetic {

/**
* 得到全排列的方法
* @param data  存放要排列的各个元素
* @return List<List<String>> 结果中的每一个List就是一种可能的排列
*/
public static List<List<String>> pl(List<String> data){

if(data.size()==1){
// 如果data中只有一个元素,那么直接得到它的全排列
List<List<String>> result= new LinkedList<List<String>>();
List<String> p = new LinkedList<>();
p.add(data.get(0));
result.add(p);
return result;
}else{
// 否则,去除第一个元素,然后得到剩下的 n-1 个元素的全排列,第一个元素插入到每一种排列中的相应位置上就可以得到所有元素的全排列了
// 也就是说, n-1 个元素的全排列中的每一种排列又可以衍生出 n 种排列
String first = data.get(0);
List<String> remainList = data.subList(1, data.size());
List<List<String>> remainPl = pl(remainList);

List<List<String>> result= new LinkedList<List<String>>();
for(int i=0;i<remainPl.size();i++){

List<String> thisOne = remainPl.get(i);
for(int j=0;j<=thisOne.size();j++){

List<String> copyOne = new LinkedList<>(thisOne);
copyOne.add(j,first);
result.add(copyOne);
}
}
return result;
}
}
}

2.集合的交并差和集合的Split,将集合按照大小划分,推荐使用Guava中的Sets Lists等 下面是apachecommons的Demo

package matrixOnto.deal.Util;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
* Created by mengxp on 2017/9/27.
*/
public class CollectionPower {
private static Logger logger = LoggerFactory.getLogger(CollectionPower.class);

public static void main(String[] args) {
String[] arrA = new String[100000];
String[] arrB = new String[100000];
for (int i=0;i<100000;i++) {
int i1 = new Random().nextInt(1000000);
arrA[i]=i1+"";
int i2 = new Random().nextInt(1000000);
arrB[i]=i2+"";
}
/*     String[] arrA = new String[]{"1", "3", "5", "6"};
String[] arrB = new String[]{"2", "3", "7", "8"};*/
long startTime=System.currentTimeMillis()/1000;
String union = new CollectionPower().collectionUnion(arrA, arrB);
//String interSection = new CollectionPower().collectionInterSection(arrA, arrB);
String disjunction = new CollectionPower().collectionDisjunction(arrA, arrB);
String subtract = new CollectionPower().collectionSubtract(arrA, arrB);
long endTime=System.currentTimeMillis()/1000;
/*   System.out.println("union: [" + union + "]");
System.out.println("interSection: [" + interSection + "]");
System.out.println("disjunction: [" + disjunction + "]");
System.out.println("subtract: [" + subtra
4000
ct + "]");*/
System.out.println("All Spend Time is :["+(endTime-startTime)+"]");
}

/**
* Union action.会去重
*
* @param arrayA
* @param arrayB
* @return
*/
public static String collectionUnion(String[] arrayA, String[] arrayB) {
String arrayC = "";
try {
List<String> a = Arrays.asList(arrayA);
List<String> b = Arrays.asList(arrayB);
Collection union = CollectionUtils.union(a, b);
arrayC = union.toString();
} catch (Exception e) {
e.printStackTrace();
logger.error("execute union action failed.....");
}
return arrayC;

}

/**
* 交集
*
* @param arrayA
* @param arrayB
* @return
*/
public static List<String> collectionInterSection(String[] arrayA, String[] arrayB) {
List<String> list=new ArrayList<>();
try {
List<String> a = Arrays.asList(arrayA);
List<String> b = Arrays.asList(arrayB);
Collection union = CollectionUtils.intersection(a, b);
list.addAll(union);
} catch (Exception e) {
e.printStackTrace();
logger.error("execute InterSection action failed.....");
}
return list;
}

/**
* union出去交集的集合
*
* @param arrayA
* @param arrayB
* @return
*/
public static String collectionDisjunction(String[] arrayA, String[] arrayB) {
String arrayC = "";
try {
List<String> a = Arrays.asList(arrayA);
List<String> b = Arrays.asList(arrayB);
Collection union = CollectionUtils.disjunction(a, b);
arrayC = union.toString();
} catch (Exception e) {
e.printStackTrace();
logger.error("execute Disjunction action failed.....");
}
return arrayC;
}

/**
* 集合(A-交集)
*
* @param arrayA
* @param arrayB
* @return
*/
public static String collectionSubtract(String[] arrayA, String[] arrayB) {
String arrayC = "";
try {
List<String> a = Arrays.asList(arrayA);
List<String> b = Arrays.asList(arrayB);
Collection union = CollectionUtils.subtract(a, b);
arrayC = union.toString();
} catch (Exception e) {
e.printStackTrace();
logger.error("execute subtract action failed.....");
}
return arrayC;
}
}


package matrixOnto.deal;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import matrixOnto.preparse.HbaseObj;

import javax.annotation.Nullable;
import java.util.List;

/**
* Created by mengxp on 2017/12/26.
*/
public class GoogleCollectionsUtils<I,R> {

public static final String TYPE_VALUE_COMBINE_STR="_";

/**
transform.toImmutableList();
transform.toArray();
transform.toImmutableSet()
* @param inputs
* @param function
* @param <I>
* @return 传入Fucntion进行类型转化
*/
public  <I> FluentIterable<R> commonTransFunction(Iterable<I> inputs, Function<I,R> function){
FluentIterable<R> transform = FluentIterable.from(inputs).transform(function);
return transform;
}

/**
* 将集合进行拆分
* @param inputs
* @param collectionSize 指定每个集合的最大的size
* @param <I>
* @return
*/
public static <I> List<List<I>> listSplit(List<I> inputs,int collectionSize){
List<List<I>> partition = Lists.partition(inputs, collectionSize);
return partition;
}

public static Function<HbaseObj, String> Function_Type_Value = new Function<HbaseObj, String>() {
@Nullable
@Override
public String apply(@Nullable HbaseObj hbaseObj) {
String hbaseObjId = hbaseObj.getId();
String hbaseObjType = hbaseObj.getType();
String id = Joiner.on(TYPE_VALUE_COMBINE_STR).join(hbaseObjType, hbaseObjId);
return id;
}

@Override
public boolean equals(@Nullable Object o) {
return false;
}
};

}


3.关于递归算法 
1.返回值Void

2.有层次或者无层递归

3.写递归时,必须把输入,输出定义清楚。

/**

* @param input
* @param infos
* @param filterVo
*/
private void recursionGraphInfos(RecursionExtendVo input, List<GraphInfo> infos, ExtendsFilterVo filterVo) {
RECURSIONEXTENDANALYSISFUTURELOG.info("Current Run Recursion level {{}} ",filterVo.getRecursionLevel());
if (filterVo.getRecursionLevel() == levelCondition) {
//达到了递归的次数
return;
}
RecursionExtendVo recursionExtendVo = queryOneByMain(input, infos, filterVo);
recursionGraphInfos(recursionExtendVo, infos, filterVo);
}

/**
*
* @param input
* @param infos
* @param filterVo
* @return
*/
private RecursionExtendVo queryOneByMain(RecursionExtendVo input, List<GraphInfo> infos, ExtendsFilterVo filterVo) {
filterVo = filterVo.leverDecrease(filterVo);
HashMultimap<String, String> hashMultimap = input.getHashMultimap();
Collection<String> values = hashMultimap.values();

HashMultimap<String, String> recusionMap = HashMultimap.create();
if (values.size() == 0) {
return input.setHashMultimap(recusionMap);
}
for (String dealNum : values) {
GraphInfo infoByTimeFilter = getInfoByTimeFilter(dealNum, filterVo, recusionMap);
infos.add(infoByTimeFilter);
}
return input.setHashMultimap(recusionMap);
}

private GraphInfo getInfoByTimeFilter(String dhhm, ExtendsFilterVo vo, HashMultimap<String, String> recusionMap) {
//比如dhhm=A  recusionMap={A->A1,A->A2,A->A3,A->A4}
String rowKey = BaseQueryBusiness.getMainRowKey("DHHM", dhhm);
GraphInfo result=new GraphInfo();
result.setEdgeSet(new HashSet<Edge>()).setVertexSet(new HashSet<Vertex>());
try {
result= commonByRecusion(table, gson, RECURSIONEXTENDANALYSISFUTURELOG, Bytes.toBytes(rowKey), OntologyServerConstants.MAIN_STORM_ENEVT, recusionMap,isFilter,vo);
} catch (IOException e) {
DealUtils.LogError(e, RECURSIONEXTENDANALYSISFUTURELOG);
}
return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: