24點遊戲(Java)
阿新 • • 發佈:2019-01-23
題目:24點遊戲是經典的紙牌益智遊戲。
常見遊戲規則:
從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。
基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式自動列出所有可能算出24的表示式,用擅長的語言(C/C++/Java或其他均可)實現程式解決問題。
24點遊戲是經典的紙牌益智遊戲
package chengxushejizuoye3; import java.util.ArrayList; import java.util.List; import com.hbhs.algorithm.HBHSAssert; /** * 計算21點遊戲<BR> * 給定數字陣列,通過+,-,*,/演算法得出最終的24點 * * @author walter.xu */ public class Count24 { public static void main(String[] args) { List<Integer> result = new ArrayList<Integer>(); result.add(2); result.add(8); result.add(2); result.add(2); int totalCount = 24; List<String> operatioins = point(result, totalCount, false); for (String str : operatioins) { System.out.println(str); } } /** * 演算法思想<BR> * 1 將所有的數值按照指定的規則生成所有的可排序的序列 * 2 針對每一個序列分別計算+,-,*,/操作,並計算最終結果,如果成功記記錄下當前的值 * * @param patternList * @param result * @return */ public static List<String> point(List<Integer> patternList, int result, boolean easyOperation) { HBHSAssert.isTrue(patternList == null || patternList.size() < 2, "Pattern must be more two"); List<String> resultList = new ArrayList<String>(); // 建立可使用的操作:加減乘除等 List<String> availableOperationList = generateAvailableOperations(easyOperation); // 構造操作的全排列組合 List<List<String>> operationList = Permutation.permutation(availableOperationList, patternList.size() - 1, true); // 構造撲克牌點數的全排列 List<List<Integer>> intList = Permutation.permutation(patternList); // 依次迭代,並計算結果 for (int i = 0; i < operationList.size(); i++) { List<String> currentOperationList = operationList.get(i); for (List<Integer> currentIntGroup : intList) { // 計算並生成公式結果,如果不為空,則表示該公式最終結果滿足24點 String caclExpression = caclAndGenerateExpression(currentIntGroup, currentOperationList, result); if (caclExpression != null) resultList.add(caclExpression); } } return resultList; } // 計算該組合並生成計算表示式 private static String caclAndGenerateExpression(List<Integer> currentIntGroup, List<String> currentOperationList, int result) { int currentCount = currentIntGroup.get(0); // 獲取第一個值作為當前結果值 int j = 1; // 下一個值得序號 for (; j < currentIntGroup.size(); j++) { if ("+".equalsIgnoreCase(currentOperationList.get(j - 1))) { if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break; // 滿足互換率,防止重複計算 currentCount += currentIntGroup.get(j); } else if ("-".equalsIgnoreCase(currentOperationList.get(j - 1))) { if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break; // 滿足互換率,防止重複計算 currentCount -= currentIntGroup.get(j); } else if ("*".equalsIgnoreCase(currentOperationList.get(j - 1))) { if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break; // 滿足互換率,防止重複計算 currentCount *= currentIntGroup.get(j); } else if ("/".equalsIgnoreCase(currentOperationList.get(j - 1))) { if (currentIntGroup.get(j - 1) % currentIntGroup.get(j) > 0) break; currentCount /= currentIntGroup.get(j); } else if (">>".equalsIgnoreCase(currentOperationList.get(j - 1))) { currentCount = currentCount >> currentIntGroup.get(j); } else if ("<<".equalsIgnoreCase(currentOperationList.get(j - 1))) { currentCount = currentCount << currentIntGroup.get(j); } else if ("^".equalsIgnoreCase(currentOperationList.get(j - 1))) { int times = currentIntGroup.get(j); int temp = currentCount; times--; while (times > 0) { currentCount *= temp; times--; } } } // 僅當全部引數都使用,並且結果等於期望結果時表示為我們所需要的組合 if (j == currentIntGroup.size()&¤tCount == result) { return formatResult(currentIntGroup, currentOperationList, result); } return null; } private static List<String> generateAvailableOperations(boolean easyOperation) { List<String> operationList = new ArrayList<String>(); operationList.add("+"); operationList.add("-"); operationList.add("*"); operationList.add("/"); if (!easyOperation) { operationList.add(">>"); operationList.add("<<"); operationList.add("^"); } return operationList; } private static String formatResult(List<Integer> intList, List<String> operationgList, int result) { StringBuilder str = new StringBuilder(); for (int i = 0; i < operationgList.size(); i++) { str.append("("); } str.append(intList.get(0)); for (int i = 1; i < intList.size(); i++) { str.append("").append(operationgList.get(i - 1)).append(intList.get(i)).append(")"); } str.append(" = ").append(result); return str.toString(); } /** * 排列組合類<BR> * 用於排列組合各種情況適用 * * @author walter.xu */ private static class Permutation { public static <T> List<List<T>> permutation(List<T> args) { return permutation(args, false); } public static <T> List<List<T>> permutation(List<T> args, boolean repeatable) { return permutation(args, args.size(), repeatable); } public static <T> List<List<T>> permutation(List<T> args, int totalSize, boolean repeatable) { List<List<T>> resultList = new ArrayList<List<T>>(); List<T> secondPart = new ArrayList<T>(); permutation(args, secondPart, resultList, totalSize, repeatable); return resultList; } private static <T> void permutation(List<T> firstPart, List<T> secondPart, List<List<T>> resultList, int totalSize, boolean repeatable) { if (totalSize == secondPart.size()) { resultList.add(secondPart); return; } for (int i = 0; i < firstPart.size(); i++) { List<T> currentFirstPart = new ArrayList<T>(firstPart); List<T> currentSecondPart = new ArrayList<T>(secondPart); currentSecondPart.add(firstPart.get(i)); if (!repeatable) { currentFirstPart.remove(i); } permutation(currentFirstPart, currentSecondPart, resultList, totalSize, repeatable); } } } }