??? 呵呵:)全組合是本人根據全排列的說法創造的,其表達的內容是:將2Cn到(n-1)Cn對應的字符串序列依次輸出(當然了,會去掉組合數值相同的組合排列,也就是只需要計算2~(n-1)/2)),這樣能夠滿足特定部門的需求。
??? 大家都知道計算排列組合的普通算法的時間復雜度是O(N*N)當N達到一定程度的時候普通的計算機是不能夠承受的,所以在計算這種對應字符串全組合需要一種高效的組合算法,使普通的機子能夠承受。對字符串進行不同m值的組合,首先我們想到的是用一個整型數組中的每一位來對應字符串中的每一個字符,這樣對數組中的元素的移動形成的不同排列,將其抽取出來對應的字符就是不同的字符組合,進行一定次數控制的循環就可以形成全組合字符序列的排列了。其具體算法如下:
組合算法 ?
? 本程序的思路是開一個數組,其下標表示1到m個數,數組元素的值為1表示其下標 ?
? 代表的數被選中,為0則沒選中。 ? ?
? 首先初始化,將數組前n個元素置1,表示第一個組合為前n個數。 ? ?
? 然后從左到右掃描數組元素值的“10”組合,找到第一個“10”組合后將其變為 ?
? “01”組合,同時將其左邊的所有“1”全部移動到數組的最左端。 ? ?
? 當第一個“1”移動到數組的m-n的位置,即n個“1”全部移動到最右端時,就得 ?
? 到了最后一個組合。 ? ?
? 例如求5中選3的組合: ? ?
? 1 ? 1 ? 1 ? 0 ? 0 ? //1,2,3 ? ?
? 1 ? 1 ? 0 ? 1 ? 0 ? //1,2,4 ? ?
? 1 ? 0 ? 1 ? 1 ? 0 ? //1,3,4 ? ?
? 0 ? 1 ? 1 ? 1 ? 0 ? //2,3,4 ? ?
? 1 ? 1 ? 0 ? 0 ? 1 ? //1,2,5 ? ?
? 1 ? 0 ? 1 ? 0 ? 1 ? //1,3,5 ? ?
? 0 ? 1 ? 1 ? 0 ? 1 ? //2,3,5 ? ?
? 1 ? 0 ? 0 ? 1 ? 1 ? //1,4,5 ? ?
? 0 ? 1 ? 0 ? 1 ? 1 ? //2,4,5 ? ?
? 0 ? 0 ? 1 ? 1 ? 1 ? //3,4,5
在具體的代碼編寫過程中,會遇到很多的問題,例如0、1轉換后的數組與1元素歸前之后的數組如何協調進行下次0、1轉換的先后次序,等等的這些問題,需要我們一個一個解決。下面我將關鍵的代碼貼出來方便大家:
??? 大家都知道計算排列組合的普通算法的時間復雜度是O(N*N)當N達到一定程度的時候普通的計算機是不能夠承受的,所以在計算這種對應字符串全組合需要一種高效的組合算法,使普通的機子能夠承受。對字符串進行不同m值的組合,首先我們想到的是用一個整型數組中的每一位來對應字符串中的每一個字符,這樣對數組中的元素的移動形成的不同排列,將其抽取出來對應的字符就是不同的字符組合,進行一定次數控制的循環就可以形成全組合字符序列的排列了。其具體算法如下:
組合算法 ?
? 本程序的思路是開一個數組,其下標表示1到m個數,數組元素的值為1表示其下標 ?
? 代表的數被選中,為0則沒選中。 ? ?
? 首先初始化,將數組前n個元素置1,表示第一個組合為前n個數。 ? ?
? 然后從左到右掃描數組元素值的“10”組合,找到第一個“10”組合后將其變為 ?
? “01”組合,同時將其左邊的所有“1”全部移動到數組的最左端。 ? ?
? 當第一個“1”移動到數組的m-n的位置,即n個“1”全部移動到最右端時,就得 ?
? 到了最后一個組合。 ? ?
? 例如求5中選3的組合: ? ?
? 1 ? 1 ? 1 ? 0 ? 0 ? //1,2,3 ? ?
? 1 ? 1 ? 0 ? 1 ? 0 ? //1,2,4 ? ?
? 1 ? 0 ? 1 ? 1 ? 0 ? //1,3,4 ? ?
? 0 ? 1 ? 1 ? 1 ? 0 ? //2,3,4 ? ?
? 1 ? 1 ? 0 ? 0 ? 1 ? //1,2,5 ? ?
? 1 ? 0 ? 1 ? 0 ? 1 ? //1,3,5 ? ?
? 0 ? 1 ? 1 ? 0 ? 1 ? //2,3,5 ? ?
? 1 ? 0 ? 0 ? 1 ? 1 ? //1,4,5 ? ?
? 0 ? 1 ? 0 ? 1 ? 1 ? //2,4,5 ? ?
? 0 ? 0 ? 1 ? 1 ? 1 ? //3,4,5
在具體的代碼編寫過程中,會遇到很多的問題,例如0、1轉換后的數組與1元素歸前之后的數組如何協調進行下次0、1轉換的先后次序,等等的這些問題,需要我們一個一個解決。下面我將關鍵的代碼貼出來方便大家:
?1?public?StringBuffer?outputRankedPrescription()?throws?IOException?{
?2?????????String?serialString?=?null;
?3?
?4?????????StringBuffer?stringBuffer?=?new?StringBuffer();
?5?
?6?????????this.inputPrescription();
?7?????????String[]?prescriptionArray?=?this.splitPrescription2Array();
?8?
?9?????????int[]?intArray?=?this.generateIntArray(prescriptionArray);
10?????????//?生成初始序列
11?????????intArray[0]?=?1;
12?????????intArray[1]?=?1;
13?????????this.printArrayElement(prescriptionArray,?intArray);
14?
15?????????intArray?=?resetArrayElement(intArray);
16?????????//?從2Cn開始,到n-2Cn結束,每一種情況下的排列都要在下面移動一次,這里還要考慮組合
17?????????//?有相同的情況,這樣就不用多輸出了
18?????????for?(int?z?=?1;?z?<?intArray.length?-?1;?z++)?{
19?????????????if?((z?-?0)?==?(intArray.length?-?z?-?1))
20?????????????????continue;
21?????????????HashMap?posHashMap?=?new?HashMap();
22?
23?????????????int[]?tempArray?=?null;
24?????????????intArray[z]?=?1;
25?????????????if?(z?!=?1)?{
26?????????????????this.printArrayElement(prescriptionArray,?intArray);
27?????????????}
28?????????????this.registerPosition(intArray,?posHashMap);
29?????????????tempArray?=?this.swapArrayElement(intArray);
30?????????????serialString?=?this.getPosSerial(tempArray);
31?????????????//?用于判斷是否之前移動過這樣的序列,移動過則不進行移動了
32?????????????if?(!posHashMap.containsKey(serialString))?{
33?????????????????printArrayElement(prescriptionArray,?tempArray);
34?????????????????this.registerPosition(tempArray,?posHashMap);
35?????????????????tempArray?=?resetArrayElement(tempArray);
36?????????????}
37?????????????//?只需要組合2到n-1的這種情況
38?????????????int[]?movedArray?=?null;
39?????????????boolean?isEqual?=?true;
40?????????????boolean?isTemp?=?false;
41?????????????boolean?isAlreadyHad?=?false;
42?????????????//?這里的循環次數是根據不同的組合來的,與前面的z值有關。
43?????????????int?loopSize?=?Combination.calculateCombinationValue(
44?????????????????????intArray.length,?z?+?1);
45?????????????while?(posHashMap.size()?!=?loopSize)?{
46?????????????????if?(movedArray?!=?null)
47?????????????????????isEqual?=?this.isArrayMatch(tempArray,?isEqual,?movedArray);
48?????????????????if?(isEqual?==?false?&&?!isAlreadyHad)?{
49?????????????????????//?這里會有movedArray?swap之后和以前一樣,無法輸出,
50?????????????????????//?又和tempArray不一樣,在這里進入死循環的情況
51?????????????????????if?(isTemp?==?true)?{
52?????????????????????????movedArray?=?this.swapArrayElement(movedArray);
53?????????????????????????serialString?=?this.getPosSerial(movedArray);
54?????????????????????}?else?{
55?????????????????????????tempArray?=?this.swapArrayElement(movedArray);
56?????????????????????????serialString?=?this.getPosSerial(tempArray);
57?????????????????????}
58?
59?????????????????????if?(posHashMap.containsKey(serialString))?{
60?????????????????????????isAlreadyHad?=?true;
61?????????????????????}
62?????????????????????if?(!posHashMap.containsKey(serialString)?&&?isTemp)?{
63?????????????????????????//?輸出
64?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
65?????????????????????????????????prescriptionArray,?movedArray,?isEqual);
66?????????????????????}?else?if((!posHashMap.containsKey(serialString)?&&?!isTemp)){
67?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
68?????????????????????????????????prescriptionArray,?tempArray,?isEqual);
69?????????????????????}
70?????????????????}?else?{
71?????????????????????tempArray?=?resetArrayElement(tempArray);
72?????????????????????tempArray?=?this.swapArrayElement(tempArray);
73?????????????????????serialString?=?this.getPosSerial(tempArray);
74?????????????????????if?(!posHashMap.containsKey(serialString))?{
75?????????????????????????//?輸出
76?
77?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
78?????????????????????????????????prescriptionArray,?tempArray,?isEqual);
79?????????????????????}?else?{
80?????????????????????????isTemp?=?true;
81?????????????????????}
82?????????????????????isAlreadyHad?=?false;
83?????????????????}
84?????????????}
85?????????}
86?????????return?stringBuffer;
87?????}
?2?????????String?serialString?=?null;
?3?
?4?????????StringBuffer?stringBuffer?=?new?StringBuffer();
?5?
?6?????????this.inputPrescription();
?7?????????String[]?prescriptionArray?=?this.splitPrescription2Array();
?8?
?9?????????int[]?intArray?=?this.generateIntArray(prescriptionArray);
10?????????//?生成初始序列
11?????????intArray[0]?=?1;
12?????????intArray[1]?=?1;
13?????????this.printArrayElement(prescriptionArray,?intArray);
14?
15?????????intArray?=?resetArrayElement(intArray);
16?????????//?從2Cn開始,到n-2Cn結束,每一種情況下的排列都要在下面移動一次,這里還要考慮組合
17?????????//?有相同的情況,這樣就不用多輸出了
18?????????for?(int?z?=?1;?z?<?intArray.length?-?1;?z++)?{
19?????????????if?((z?-?0)?==?(intArray.length?-?z?-?1))
20?????????????????continue;
21?????????????HashMap?posHashMap?=?new?HashMap();
22?
23?????????????int[]?tempArray?=?null;
24?????????????intArray[z]?=?1;
25?????????????if?(z?!=?1)?{
26?????????????????this.printArrayElement(prescriptionArray,?intArray);
27?????????????}
28?????????????this.registerPosition(intArray,?posHashMap);
29?????????????tempArray?=?this.swapArrayElement(intArray);
30?????????????serialString?=?this.getPosSerial(tempArray);
31?????????????//?用于判斷是否之前移動過這樣的序列,移動過則不進行移動了
32?????????????if?(!posHashMap.containsKey(serialString))?{
33?????????????????printArrayElement(prescriptionArray,?tempArray);
34?????????????????this.registerPosition(tempArray,?posHashMap);
35?????????????????tempArray?=?resetArrayElement(tempArray);
36?????????????}
37?????????????//?只需要組合2到n-1的這種情況
38?????????????int[]?movedArray?=?null;
39?????????????boolean?isEqual?=?true;
40?????????????boolean?isTemp?=?false;
41?????????????boolean?isAlreadyHad?=?false;
42?????????????//?這里的循環次數是根據不同的組合來的,與前面的z值有關。
43?????????????int?loopSize?=?Combination.calculateCombinationValue(
44?????????????????????intArray.length,?z?+?1);
45?????????????while?(posHashMap.size()?!=?loopSize)?{
46?????????????????if?(movedArray?!=?null)
47?????????????????????isEqual?=?this.isArrayMatch(tempArray,?isEqual,?movedArray);
48?????????????????if?(isEqual?==?false?&&?!isAlreadyHad)?{
49?????????????????????//?這里會有movedArray?swap之后和以前一樣,無法輸出,
50?????????????????????//?又和tempArray不一樣,在這里進入死循環的情況
51?????????????????????if?(isTemp?==?true)?{
52?????????????????????????movedArray?=?this.swapArrayElement(movedArray);
53?????????????????????????serialString?=?this.getPosSerial(movedArray);
54?????????????????????}?else?{
55?????????????????????????tempArray?=?this.swapArrayElement(movedArray);
56?????????????????????????serialString?=?this.getPosSerial(tempArray);
57?????????????????????}
58?
59?????????????????????if?(posHashMap.containsKey(serialString))?{
60?????????????????????????isAlreadyHad?=?true;
61?????????????????????}
62?????????????????????if?(!posHashMap.containsKey(serialString)?&&?isTemp)?{
63?????????????????????????//?輸出
64?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
65?????????????????????????????????prescriptionArray,?movedArray,?isEqual);
66?????????????????????}?else?if((!posHashMap.containsKey(serialString)?&&?!isTemp)){
67?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
68?????????????????????????????????prescriptionArray,?tempArray,?isEqual);
69?????????????????????}
70?????????????????}?else?{
71?????????????????????tempArray?=?resetArrayElement(tempArray);
72?????????????????????tempArray?=?this.swapArrayElement(tempArray);
73?????????????????????serialString?=?this.getPosSerial(tempArray);
74?????????????????????if?(!posHashMap.containsKey(serialString))?{
75?????????????????????????//?輸出
76?
77?????????????????????????movedArray?=?manageArrayOutput(posHashMap,
78?????????????????????????????????prescriptionArray,?tempArray,?isEqual);
79?????????????????????}?else?{
80?????????????????????????isTemp?=?true;
81?????????????????????}
82?????????????????????isAlreadyHad?=?false;
83?????????????????}
84?????????????}
85?????????}
86?????????return?stringBuffer;
87?????}
本文依據《創作共用約定》之“署名-禁止派生-非商業用途”方式發布,即你可以免費拷貝、分發、呈現和表演當前作品,但是必須基于以下條款:
署名:你必須明確標明作者的名字。
非商業用途:你不可將當前作品用于商業目的。
禁止派生:你不可更改、轉變或者基于此作品重新構造為新作品。
對于任何二次使用或分發,你必須讓其他人明確當前作品的授權條款。
在得到作者的明確允許下,這里的某些條款可以放棄。
根據你的思路, 寫了一個簡單的算法,好像不需要上邊那么復雜。這里我用true代表1, false代表0。看看有沒有問題。
---------------------------------------
public class TestFastCombination {
/**
* @param args
*/
public static void main(String[] args) {
TestFastCombination comb = new TestFastCombination();
comb.combine(5);
}
private void combine(int totalSize){
//int currentSize = 0;
boolean[] myList = new boolean[totalSize];
for(int currentSize = 3; currentSize<totalSize-1;currentSize++){
//initial
for(int i=0;i<totalSize;i++){
if(i<currentSize){
myList[i] = true;
}
else{
myList[i] = false;
}
}
//PrintFirst combination
for(int i = 0;i<myList.length ;i++){
System.out.print(myList[i]+" ");
}
System.out.println();
//start to search 10 and move left 1s to left most
findAndChange10(myList);
}
}
private void findAndChange10(boolean[] tempList){
int leftOneNumbers = 0;
int leftZeroNumbers = 0;
boolean isFirstPairMatch = false;
do{
leftOneNumbers = leftZeroNumbers = 0;
isFirstPairMatch = false;
for(int i=0;i<tempList.length-1 ; i++){
if(tempList[i]==true ){
leftOneNumbers++;
if(tempList[i+1]==false){
tempList[i]=false;
tempList[i+1]=true;
leftOneNumbers--;
if(i==0){
isFirstPairMatch = true;
}
break;
}
}
else{
leftZeroNumbers++;
}
}
if(leftOneNumbers>0){
for(int j=0;j<leftOneNumbers;j++){
tempList[j]=true;
}
if(leftZeroNumbers>0){
for(int j=0;j<leftOneNumbers;j++){
tempList[leftOneNumbers+j]=false;
}
}
}
//Here I got a other possible combination
for(int i = 0;i<tempList.length ;i++){
System.out.print(tempList[i]+" ");
}
System.out.println();
}
while(leftOneNumbers>0 ||(isFirstPairMatch));
}
}
true true true false false
true true false true false
true false true true false
false true true true false
true true false false true
true false true false true
false true true false true
true false false true true
false true false true true
false false true true true