日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

任意1-10中的4个数字,使用加减乘除计算得出24结果的可能组合(java版),很多人小时候都玩过...

發布時間:2025/3/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 任意1-10中的4个数字,使用加减乘除计算得出24结果的可能组合(java版),很多人小时候都玩过... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 需求;
  • 需求該如何分析呢,怎么劃分成小需求呢?
  • 如何把小需求編排成完整需求;
  • 學有所得

  • 學會分析需求,由哪些組成(規則,邏輯等);
  • 能把的需求分解成很多子需求、或孫需求、或童孫需求,直到每個需求很清晰可實施地為止
  • 學會把各種子孫需求,通過組合編排,最終成為一個完整的大需求解決方案
  • 需求

    需求:任意1-10中的4個數字,使用加減乘除計算得出24結果的可能組合;
    通過初步分析,我們可以得到如下規則:
    規則:1、任意1-10中的4個數字;
    2、使用加減乘除計算得出24;

    3、在任何一次計算中不能出現小數,
    比如:(4.0 + 8.0) / (3.0 / 6.0) = 24.0,這種是不算的,雖然最終結果是24,因為3/6=0.5;(8.0 / 3.0) * (4.0 + 5.0) = 24.0,雖然最終為24,但是在第一步結果卻是小數,所以不成立;代碼如下

    /*** 是否為合法的計算結果* @param result* @return*/public static boolean isValidResult(double result){if (result<1){return false;}return result == Math.floor(result);} View Code

    4、整個運算中應該使用double類型,因為整數相除,使用int類型,在計算機中,會把余數抹掉,直接取整,這樣就會造成結果不正確;

    那需求該如何分析呢,怎么劃分成小需求呢?

    一般來說我們都會通過案例來分析,比如:這個需求,我們使用傳統的計算,假設我們已經有這四個數[3,4,8,6],可能會有如下組合:

    方案:((4.0 + 8.0) * 6.0) / 3.0=24.0;
    方案:((3.0 * 4.0) - 8.0) * 6.0=24.0;
    方案:((8.0 - 6.0) * 3.0) * 4.0=24.0;
    方案:((4.0 + 8.0) / 3.0) * 6.0=24.0;

    方案:(4.0 * 3.0) * (8.0 - 6.0) = 24.0;
    方案:(6.0 / 3.0) * (4.0 + 8.0) = 24.0;

    我們暫時先分析這個幾個方案,大家看到這里,可以先思考一下有什么規律,有什么規則;

    ....................................................................................................Thinking..............................

    從這些方案中,我們可以得出如下蹊蹺之處:
    1、所有的方案中,都在這四個數的所有可能排列組合中(我記憶之中,應該是高中數學的知識點);
    2、我們可以把計算法則歸納為兩種,所有的都可以歸納到一下兩種中去;
    第一、從左到右的依次計算;
    第二、兩兩組合,前兩個數計算結果和后兩個數的計算結果再次計算;
    第三、每個方案都有3個運算符;

    不知道大家是不是和我發現的一樣不,或者說有更多的發現;我認為不管什么發現都可以先列出來,然后在逐個去去除一些太離譜的發現;
    我們再繼續順藤摸瓜,到此我們可以把需求分解如下:

    我們繼續分析需求,看看是否可以再次分解

    從上面的需求中我們可以進一步進行分解

    第一、如何獲取四個數的所有排列組合?
    1、舉例,我們繼續使用案列來分析,比如 [3,4,8,6]
    [3,4,8,6](基準)
    [4,3,8,6](第二和第一調換)
    [3,8,4,6] [8,3,4,6](第三和第二調換,第二和第一調換)
    [3,4,6,8] [3,6,4,8] [6,3,4,8] (第四和第三調換, 第三和第二調換,第二和第一調換)
    這樣是不是所有的排列組合呢?顯然不是?因為還有三種基準進行上面的排列組合,也就是上面每行最后一列
    [4,3,8,6](基準2)
    [8,3,4,6](基準3)
    [6,3,4,8](基準4)
    2、通過上面的舉例,我們就可以先獲取所有的基準組合;
    3、通過上面,我們可以知道每種基準的所有組合;
    4、通過上面的方法獲取的組合會有重復,需要前需要去重;
    這樣我們就能獲取4個數的所有排列組合;我感覺這種獲取所有排列組合的算法很笨重(有沒有感覺有點想冒泡排序),不優雅,肯定有更優的方案,只是我不知道而已,如果知道的可以留言,謝謝;
    所有排列分析到此,是不是還需要繼續分析,可以繼續思考;本人感覺可以落地了;如果覺得需要繼續分析的,可以繼續分解,知道自己很清晰,知道怎么干為止(這個因人而異);請看代碼;

    獲取所有基準代碼:

    double[] array = {3, 4, 6, 8};List<double[]> resultAllList = new ArrayList<>();List<double[]> list = new ArrayList<>();list.add(array);list.add(new double[]{array[1], array[2], array[3], array[0]});list.add(new double[]{array[2], array[3], array[0], array[1]});list.add(new double[]{array[3], array[0], array[1], array[2]}); View Code

    獲取每個基準的所有排列組合:

    /*** 獲取array的所有可能組合** @param list* @param array*/public static void getAllArray(List<double[]> list, double[] array) {if (!exists(list, array)) {list.add(array);}for (int i = 1; i < 4; i++) {double[] arrayCopy = Arrays.copyOf(array, array.length);List<double[]> newList = getArrayList(arrayCopy, i);Iterator<double[]> iterator = newList.iterator();while (iterator.hasNext()) {double[] temp = iterator.next();if (!exists(list, temp)) {list.add(temp);}}}}/*** 獲取array下標遇到i的位置左右組合** @param array* @param i* @return*/public static List<double[]> getArrayList(double[] array, int i) {List<double[]> list = new ArrayList<>();for (int j = i; j > 0; j--) {double temp = array[j];array[j] = array[j - 1];array[j - 1] = temp;list.add(array);array = Arrays.copyOf(array, array.length);}return list;} View Code

    第二,對于算法法則該如何繼續分析呢?我們可以繼續使用舉例
    從上面隨意獲取一種排列組合,比如:[3,4,8,6]
    1、從左到右的組合,在上面四個數字中,任意兩個數中,我們可以有+,- ,*,/這四種算法,這又是一種計算的所有排列組合,并把結果和24對比,如果相等,那就是可行方案;
    那我們是不是繼續使用上面獲取組合的方式呢?顯然不是,這里關鍵點在于:任意兩個數中都有+-*/的算法,這里我們可以使用三個for循環解決;
    舉例:((3.0 * 4.0) - 8.0) * 6.0=24.0;

    /*** 計算array能算24點的所有組合,從左到右的順序** @param* @throws Exception*/public static int caculate24Point(double[] array) throws Exception {int count = 0;if (array.length != 4) {throw new Exception("不是四個數");}for (String op : operators) {String expressionStr = "";double result = getTwoNumCaculate(array[0], array[1], op);if (!isValidResult(result)){continue;}expressionStr = String.format("(%s %s %s)", array[0], op, array[1]);for (String op2 : operators) {double result1 = getTwoNumCaculate(result, array[2], op2);if (!isValidResult(result1)){continue;}String expressionStr2 = String.format("(%s %s %s)", expressionStr, op2, array[2]);for (String op3 : operators) {double result2 = getTwoNumCaculate(result1, array[3], op3);String expressionStr3 = String.format("%s %s %s", expressionStr2, op3, array[3]);if (result2 == 24.0d) {count++;System.out.println(String.format("方案:%s=%s", expressionStr3, result2));}}}}return count;} View Code

    ?

    2、兩兩組合,思路和上面有些相似,

    前兩個數的任意計算結果1,
    后兩個數的任意計算結果2,
    結果1和結果2的任意計算結果3,
    結果3和24對比,如果相等,那就是可行方案;
    舉例:(3.0 * 4.0) * (8.0 - 6.0) = 24.0;

    /*** 計算array能算24點的所有組合 ,兩兩組合** @param array* @return* @throws Exception*/public static int caculate24Point2(double[] array) throws Exception {int count = 0;if (array.length != 4) {throw new Exception("不是四個數");}for (String op : operators) {double result1 = getTwoNumCaculate(array[0], array[1], op);if (!isValidResult(result1)){continue;}String expressionStr1 = String.format("(%s %s %s)", array[0], op, array[1]);for (String op2 : operators) {double result2 = getTwoNumCaculate(array[2], array[3], op2);if (!isValidResult(result2)){continue;}String expressionStr2 = String.format("(%s %s %s)", array[2], op2, array[3]);for (String op3 : operators) {double result3 = getTwoNumCaculate(result1, result2, op3);String expressionStr3 = String.format("%s %s %s", expressionStr1, op3, expressionStr2);if (result3 == 24.0d) {count++;System.out.println(String.format("方案: %s = %s", expressionStr3, result3));}}}}return count;} View Code

    ?

    ?

    某一種四個數的所有運算排列通過上面的方式我們可以全部獲取,分析到此,我覺得代碼可以落地,當然,如果你覺得還不夠清晰,可以繼續分析,直到自己清晰為止,這里我只是提供分解需求的思路而已;在軟件工程中,我們必定先分析需求,然后分解需求,我們有四色分析方式,我們還有DDD領域的分析方式等,都是需要通過逐步分解成更小的需求來反復驗證的;

    ?

    到目前為止我們可以得出如下思維導圖

    ?

    把各種子孫需求,通過組合編排,最終成為一個完整的大需求解決方案

    最后,我們把每個小的需求加上一些規則邏輯組合成完整的大需求,我們暫時叫做編排吧;
    這里其實也是一個難點,很多人希望一次性把代碼寫完整,寫正確,其實這種思路是不正確的,這樣只會增加代碼的難度,一次性能把代碼寫的有多完整多正確,這個跟每個人的編程經驗熟練度有關;
    不管編程多牛,從無到有的敲代碼方向不是一次性把左右的代碼完成,重點方向把核心邏輯思路編寫上,其次才逐步把一些細節邏輯規則加上去,這個就和我們小時候學畫畫一樣,畫一顆樹先畫主干然后畫葉子最后添加果子和花之類的;

    ?

    到目前為止是否完整呢?其實還差一點,任意的1-10的數字從哪里獲取,不過需求沒有明確,可以是用戶輸入,數據庫獲取,其他接口的傳入,我們這里就定位用戶輸入吧

    獲取用戶輸入代碼如下:

    double[] array = new double[4];int index=0;Scanner scanner=new Scanner(System.in);while (index<4){System.out.println(String.format("請輸入第%s個1-10的整數",index+1));String tempNumStr=scanner.nextLine();if(!StringUtils.isNumeric(tempNumStr)){System.out.println("你輸入的不是一個整數");continue;}double tmpNum=Double.valueOf(tempNumStr);if (tmpNum<0 || tmpNum>10){System.out.println("你輸入的數字不是1-10的數字");continue;}array[index++]=tmpNum;}System.out.println(String.format("你輸入的4個1-10的整數為%s,%s,%s,%s",array[0],array[1],array[2],array[3])); View Code

    ?

    最終完整代碼如下:

    import org.apache.commons.lang3.StringUtils;import java.util.*;/*** Author:* Date:*/ public class Point24Caculator {/*** 計算24點中可以到的操作*/private static String[] operators = {"+", "-", "*", "/"};public static void main(String[] args) throws Exception {double[] array = new double[4];int index=0;Scanner scanner=new Scanner(System.in);while (index<4){System.out.println(String.format("請輸入第%s個1-10的整數",index+1));String tempNumStr=scanner.nextLine();if(!StringUtils.isNumeric(tempNumStr)){System.out.println("你輸入的不是一個整數");continue;}double tmpNum=Double.valueOf(tempNumStr);if (tmpNum<0 || tmpNum>10){System.out.println("你輸入的數字不是1-10的數字");continue;}array[index++]=tmpNum;}System.out.println(String.format("你輸入的4個1-10的整數為%s,%s,%s,%s",array[0],array[1],array[2],array[3]));System.out.println("結果如下:");List<double[]> resultAllList = new ArrayList<>();List<double[]> list = new ArrayList<>();list.add(array);list.add(new double[]{array[1], array[2], array[3], array[0]});list.add(new double[]{array[2], array[3], array[0], array[1]});list.add(new double[]{array[3], array[0], array[1], array[2]});for (int i = 0; i < list.size(); i++) {getAllArray(resultAllList, Arrays.copyOf(list.get(i), list.get(i).length));}int sum = 0;Iterator<double[]> iterator = resultAllList.iterator();while (iterator.hasNext()) {double[] tempArray = iterator.next();sum += caculate24Point(tempArray);sum += caculate24Point2(tempArray);}System.out.println("總共方案數量:" + sum);}/*** 獲取array的所有可能組合** @param list* @param array*/public static void getAllArray(List<double[]> list, double[] array) {if (!exists(list, array)) {list.add(array);}for (int i = 1; i < 4; i++) {double[] arrayCopy = Arrays.copyOf(array, array.length);List<double[]> newList = getArrayList(arrayCopy, i);Iterator<double[]> iterator = newList.iterator();while (iterator.hasNext()) {double[] temp = iterator.next();if (!exists(list, temp)) {list.add(temp);}}}}/*** 獲取array下標遇到i的位置左右組合** @param array* @param i* @return*/public static List<double[]> getArrayList(double[] array, int i) {List<double[]> list = new ArrayList<>();for (int j = i; j > 0; j--) {double temp = array[j];array[j] = array[j - 1];array[j - 1] = temp;list.add(array);array = Arrays.copyOf(array, array.length);}return list;}/*** array是否存啊在list中** @param list* @param array* @return*/public static boolean exists(List<double[]> list, double[] array) {Iterator<double[]> iterator = list.iterator();while (iterator.hasNext()) {double[] tmpArray = iterator.next();if (tmpArray[0] == array[0] && tmpArray[1] == array[1] && tmpArray[2] == array[2] && tmpArray[3] == array[3]) {return true;}}return false;}/*** 計算array能算24點的所有組合,從左到右的順序** @param* @throws Exception*/public static int caculate24Point(double[] array) throws Exception {int count = 0;if (array.length != 4) {throw new Exception("不是四個數");}for (String op : operators) {String expressionStr = "";double result = getTwoNumCaculate(array[0], array[1], op);if (!isValidResult(result)){continue;}expressionStr = String.format("(%s %s %s)", array[0], op, array[1]);for (String op2 : operators) {double result1 = getTwoNumCaculate(result, array[2], op2);if (!isValidResult(result1)){continue;}String expressionStr2 = String.format("(%s %s %s)", expressionStr, op2, array[2]);for (String op3 : operators) {double result2 = getTwoNumCaculate(result1, array[3], op3);String expressionStr3 = String.format("%s %s %s", expressionStr2, op3, array[3]);if (result2 == 24.0d) {count++;System.out.println(String.format("方案:%s=%s", expressionStr3, result2));}}}}return count;}/*** 計算array能算24點的所有組合 ,兩兩組合** @param array* @return* @throws Exception*/public static int caculate24Point2(double[] array) throws Exception {int count = 0;if (array.length != 4) {throw new Exception("不是四個數");}for (String op : operators) {double result1 = getTwoNumCaculate(array[0], array[1], op);if (!isValidResult(result1)){continue;}String expressionStr1 = String.format("(%s %s %s)", array[0], op, array[1]);for (String op2 : operators) {double result2 = getTwoNumCaculate(array[2], array[3], op2);if (!isValidResult(result2)){continue;}String expressionStr2 = String.format("(%s %s %s)", array[2], op2, array[3]);for (String op3 : operators) {double result3 = getTwoNumCaculate(result1, result2, op3);String expressionStr3 = String.format("%s %s %s", expressionStr1, op3, expressionStr2);if (result3 == 24.0d) {count++;System.out.println(String.format("方案: %s = %s", expressionStr3, result3));}}}}return count;}/*** 是否為合法的計算結果* @param result* @return*/public static boolean isValidResult(double result){if (result<1){return false;}return result == Math.floor(result);}private static double getTwoNumCaculate(double num1, double num2, String operator) throws Exception {switch (operator) {case "+":return num1 + num2;case "-":return num1 - num2;case "*":return num1 * num2;case "/":return num1 / num2;default:throw new Exception("運算符不符合規范");}} } View Code

    ?

    ?

    學有所得

  • 是否學會了這種分析思路
  • 是否這種需求分析思路可以運用在地方?
  • 這種把每個原子需求編排成一個完整大需求,是否可以在他地方使用?
  • 最后效果圖:

    ?

    轉載于:https://www.cnblogs.com/lechengbo/p/10815016.html

    總結

    以上是生活随笔為你收集整理的任意1-10中的4个数字,使用加减乘除计算得出24结果的可能组合(java版),很多人小时候都玩过...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。