需求:传递给你一个集合(List,Array不限),不为空,现在需要写个算法实现如下逻辑: 以List为例: List<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); 现在list里面的值为{"A","B","C"} 现在用*替换其中任意一个或者多个值来得到一个集合,里面存着所有的可能性数据,这个例子的就是{"AB*","A**","A*C","*BC","*B*","**C","***"},诸如此类,最后这个集合的长度肯定是2的N次方减1,求解此算法
import java.util.List;public class HuiSu {
public static void main(String[] args) {
List<List<Integer>> resultList = new ArrayList<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
List<String> valueList = new ArrayList<String>();
valueList.add("A");
valueList.add("B");
valueList.add("C");
valueList.add("D");
List<Integer> li = new ArrayList<Integer>();
PowerSet(0, list, li, resultList);
List<List<String>> lastList = new ArrayList<List<String>>();
lastList = doChange(resultList, valueList);
System.out.println(lastList); } // 回溯法求幂集
public static void PowerSet(int i, List<Integer> list, List<Integer> li, List<List<Integer>> resultList) { if (i > list.size() - 1) {
List<Integer> tempList = new ArrayList<Integer>();
for (Integer s : li) {
tempList.add(s);
}
resultList.add(tempList);
} else {
li.add(list.get(i));// 左加
PowerSet(i + 1, list, li, resultList); // 递归方法
li.remove(list.get(i)); // 右去
PowerSet(i + 1, list, li, resultList);
}
} public static List<List<String>> doChange(List<List<Integer>> resultList, List<String> valueList) {
List<List<String>> newResultList = new ArrayList<List<String>>();
for (List<Integer> newList : resultList) {
if(newList != null && newList.size() > 0){
int startCount = 1;
List<String> newResult = new ArrayList<String>();
for (Integer j : newList) {
for (int k = startCount; k <= valueList.size(); k++) {
if (j == k) {
newResult.add(valueList.get(k - 1));
startCount = j + 1;
break;
} else {
newResult.add("*");
}
}
}
if(newResult.size() < valueList.size()){
int resultSize = newResult.size();
for(int i = 1 ; i <= valueList.size() - resultSize ; i++){
newResult.add("*");
}
}
newResultList.add(newResult);
}else {
List<String> newResult = new ArrayList<String>();
for(int i = 1 ; i <= valueList.size() ; i++){
newResult.add("*");
}
newResultList.add(newResult);
} }
return newResultList;
}}这是我写的一个算法你可以试试看看,谢谢你的答复
再,如果把每一位当作二进制的位数,0表示不选,1表示选择,则有3位数,可已通过 0b000,三位二进制数表示
0b001表示只选择最后一个,0b111表示三个都选了
以前写过很多类似的了
for example
public class Test {
public static void main(Srting[] args) {
List<String> list = new ArrayList<String>(
Arrays.asList(new String[]{"A", "B", "C"})
);
combine(list);
} public static void combine(List<String> list) {
int[] dig = new int[list.size()];
dig[dig.length-1] = 1;
StringBuilder sb = new StringBuilder();
while (dig[0] < 2) {
sb.delete(0, sb.length());
for (int i=0; i<dig.length; i++) {
if (dig[i] == 1) {sb.append("*");}
else {sb.append(list.get(i));}
}
System.out.println(sb);
dig[dig.length-1]++;
for (int i=dig.length-1; i>0; i--) {
if (dig[i] == 2) {
dig[i] = 0;
dig[i-1]++;
} else {
break;
}
}
}
}
}
//char[]变成List<String>自己会吧
public static void main(String[] args) {
sf("ABC");
} /**
* @param keys 不重复的key
*/
public static void sf(String keys) {
//最高位数
int max = (int) Math.pow(2, keys.length());
//0为不选
for (int i = 1; i < max; i++) {
System.out.println(sf(keys,i));
}
} /**
* 将k中,n的位数上为1的代替为*
* @param k
* @param n
* @return
*/
public static String sf(String k, int n) {
StringBuilder b = new StringBuilder();
for (int i = k.length() - 1, z = n; i > -1; i--) {
if (z % 2 == 0) {
b.append(k.charAt(i));
} else {
b.append("*");
}
z >>>= 1;
}
return b.reverse().toString();
}