數字間增加加減乘除得到的可能值算法

package util;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Test {
 public static void main(String[] args) throws ParseException {
  List<Integer> listnum = new ArrayList<Integer>()
{
{
add(5);
add(1);
add(1);
add(0);
add(2);
 }
};
  List<Integer> finalReslut = new Test().method(listnum);
  Collections.sort(finalReslut);
  System.out.println(finalReslut);
 }
private  List<Integer> method(List<Integer> listnum){
List<Integer> listReslut = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
List<Integer> signList = new ArrayList<Integer>();
for (int k = 0; k < listnum.size()-1; k++) {
signList.add(0);
}
for (int i = 0; i < Math.pow(4, listnum.size()-1); i++) {
Integer m = new Integer(i);
Integer j = 0;
while(m > 0){
signList.set(signList.size()-1-j, m%4);
j++;
m = m/4;
}
set.add(myMethod(signList,listnum));
}
for(Integer temp : set){
listReslut.add(temp);
}
return listReslut;
}
 
private  int myMethod(List<Integer> list,List<Integer> listnum) {
List<Integer> listSignCopy = new ArrayList<Integer>();
List<Integer> listNumCopy = new ArrayList<Integer>();
listSignCopy.addAll(list);
listNumCopy.addAll(listnum);
while(listSignCopy.contains(2) || listSignCopy.contains(3)){
//合併乘除,一次只去除一個乘號或者除號
for (int m = 0; m < listSignCopy.size(); m++) {
if(listSignCopy.get(m) == 2 || listSignCopy.get(m) == 3){
try {//如果被除數是0可能會報錯,直接跳過
listNumCopy.set(m, listSignCopy.get(m) == 2 ? listNumCopy.get(m)*listNumCopy.get(m+1) : listNumCopy.get(m)/listNumCopy.get(m+1));
} catch (Exception e) {
}
listNumCopy.remove(m+1);
listSignCopy.remove(m);
break;
}
}
}
//合併加減
while(listSignCopy != null && listSignCopy.size() > 0){
 listNumCopy.set(0, listSignCopy.get(0) == 0 ? listNumCopy.get(0)+listNumCopy.get(1) : listNumCopy.get(0)-listNumCopy.get(1));
 listNumCopy.remove(1);
 listSignCopy.remove(0);
}
return listNumCopy.get(0);
}

}




主要思路當然是遍歷所有情況運算得出值存入set。然後拷貝到list排序。數字集合listNum,運算符號集合signList
紅色myMethod是運算邏輯這裏採用的是  先乘除後加減的原則  合併2個數並去除運算符號, 比如 2*5+9-5經過一次合併後10+9-5。直到合併至沒有運算符號即爲該次的最終值。
藍色method構建所有運算符號的排列組合,不知道別人的排列組合用的什麼算法實現,我這裏的思路是:首先運算符號集合signList中0 1 2 3分別代表加簡乘除運算法則
且長度總是數字集listNum.size()-1;初始化signList默認爲0,我們只需遍歷出0 1 2 3的排列組合,這裏想到了四進制算法。
對4輾轉相除取餘數的值倒序爲該次排列(其實也不用倒序,反正要求出所有排列,不顧倒序確實更好操作,因爲正序還要判斷該次排列的長度),然後將改次排列存入signList調用method即遍歷出所有可能值。

本來是csdn上別人的一個提問,然後搗騰出這個通用算法,解決了我多年對於  遍歷循環次數爲變量的循環  的疑問,那便是利用進制轉換巧妙解決,只需將method中的  4  換成變量即可,同時排列組合的問題也可以用該方法,感覺開啓了新世界的大門-_,-
本人於qq空間有發表本文,略有修改。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章