中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于JS如何實現計算24點

發布時間:2020-07-23 13:51:27 來源:億速云 閱讀:236 作者:小豬 欄目:開發技術

小編這次要給大家分享的是基于JS如何實現計算24點,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

前言

  休息的時候無意間看到群里有人發出了華為的校招題,一開始看題目的時候覺得很簡單,于是晚上就試著寫了一下,結果寫的過程中打臉,不斷的整理邏輯不斷的重寫,但我的性格又是不做出來晚上睡不好的那種,于是在做出來的時候就分享給大家(快凌晨三點了有木有,這校招題難度都達到這級別了?o(╥﹏╥)o)

題目描述

基于JS如何實現計算24點

審題要注意:1+2+3*4是前面三個已經相加為6再乘4,沒有括號!!

代碼:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>21點</title>
 <script>

   // 牌和對應的權重
   const pokerBox = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];//下標+1剛好就是對應的分值
   let calcSym = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];//0,1,2 3,4 5,6,7 8,9分別對應+-*/

   function Calculate(a, b, c) {
    if (c <= 2) return a + b;
    if (c <= 4) return a - b;
    if (c <= 7) return a * b;
    if (c <= 9) return a / b;
    return -1;
   }

   function filter(c) {
    if (c <= 2) return "+";
    if (c <= 4) return "-";
    if (c <= 7) return "*";
    if (c <= 9) return "/";
    return;
   }

   let answer = "NONE";//回復的字符串 默認回復NONE,表示無解
   function Calculate24(a, b, c, d, C1, C2, C3) {
    let sum = Calculate(Calculate(Calculate(a, b, C1), c, C2), d, C3);
    if (sum === 24) answer = `公式為:${a} ${filter(C1)} ${b} ${filter(C2)} ${c} ${filter(C3)} $aegqsqibtmh = ${sum}`;
    return sum;
   }

   // 全排列
   //這里的全排序就是把原先的數組復制一個出來,然后新數組代替原先數組刪除該值,temp數組添加該值,當新數組的長度為0,說明轉移完成,就把temp數組放入matrix數組中
   function permutation(pokers) {
    let matrix = [];
    const subFunc = (arr, temp) => {
     if (temp.length > 4) temp.length = 4;//為了避免過長
     if (arr.length === 0) matrix.push(temp);
     arr.forEach((elem, i) => {
      subFunc([...arr.slice(0, i), ...arr.slice(i + 1)], [...temp, elem]);
     });
    }
    subFunc(pokers, []);
    return matrix;
   };

   // 計算總數為24
   function Count24(a, b, c, d) {
    calcSym.sort((x, y) => x - y);//升序排序
    if (Calculate24(a, b, c, d, calcSym[0], calcSym[1], calcSym[2]) === 24) return true;//第一次判斷如果符合就不需要執行下面的循環了
    let i = 1;//上面判斷了一次,因此這里從1開始
    if (calcSym.length <= 10) calcSym = [...new Set(permutation(calcSym).flatMap(item=>item.join()))].map(item=>item.split(","));//二維數組去重,并獲取全排的數組(即每一種可能性)
    while (true) {
     if (Calculate24(a, b, c, d, calcSym[i][0], calcSym[i][1], calcSym[i][2]) === 24) return true;
     if (i < calcSym.length - 1) i++;
     else return false;//如果數組遍歷完都沒
    };
    return false;
   }

   function init() {
    if (calcSym.length === 12) calcSym = permutation(calcSym);//獲取全排的數組(即每一種可能性)
   }
   init();//初始化就立即執行

   // 對輸入的數字進行一次全排
   function calcNumber(arr) {
    if (Count24(arr[0], arr[1], arr[2], arr[3])) return true;//這一步滿足那么下面就不用執行permutation了,因為底層是遞歸,很消耗性能
    let i = 1;
    if (arr.length <= 4) arr = [...new Set(permutation(arr).flatMap(item=>item.join()))].map(item=>item.split(","));//二維數組去重
    if (arr.length > 1) {
     while (true) {
      if (Count24(arr[i][0], arr[i][1], arr[i][2], arr[i][3])) return true;
      if (i < arr.length - 1) i++;
      else return answer = "NONE";
     }
    };
    return answer = "NONE";
   }

   // 當我輸入完光標離開的時候就開始判斷并計算
   function pokers(event) {
    let arr = event.value.trim().split(" ");
    if (arr.length > 4) {
     arr.length = 4;
     document.getElementById("poker").value = arr.join(' ');
     alert("您輸入的牌數大于4張,這邊自動幫您刪除");
    }
    if (arr.some(item => !pokerBox.includes(item))) alert("ERROR");
    else {
     let arrNew = arr.map(item => { return pokerBox.indexOf(item) + 1 });//計算權重
     calcNumber(arrNew);//執行計算
    }
   }
   function dialog() { alert(answer) };
 </script>
</head>

<body>
 <!-- 這里設置為失去焦點就開始計算是為了盡量減少用戶等待的時間,但注意不要設置為輸入就開始計算,否則瀏覽器會卡到崩潰 -->
 <!-- 由于是遍歷數組獲取結果,如果用戶輸入的值不為24,那么系統會查詢的很慢,這個時候的優化方案有:
 一、每次用戶輸入的值和對應的回復保存在一個數組內,下次用戶輸入時先判斷是否在該數組內,不在的時候再執行計算
 二、我們可以先排除一部分不可能的值放入數組,比如用戶輸入2 2 2 2或A A A A,這種怎么算都不可能為24,如果用戶輸入的為這一類就直接Pass
 三、先把最耗時的calcSym數組的全排改為用戶一進入頁面就先異步加載計算 -->
 <input type="text" onblur="pokers(this)" name="21" id="poker">
 <input type="button" onclick="dialog()" value="confirm" />
</body>

</html>

實現的效果:

基于JS如何實現計算24點

基于JS如何實現計算24點

基于JS如何實現計算24點

總結思路:

  題目第一眼看到就應該想到遞歸,之前我是把加減乘除都設為一個方法,想采用面向切面的方式進行計算,但是這種方式邏輯復雜且無法計算復雜一點的公式,因此就改為直接把所有可能出現的結果都拿出來一一比對,只要其中一個為24就終止循環,否則循環結束之后返回NONE;

  calcSym=[0,1,2,3,4,5,6,7,8,9];//0,1,23,45,6,78,9分別對應+-*/,這里為三個+,兩個-,三個*,兩個除,大家可以推理得出,6+6+6+6,1*2*3*4,2*13-1-1,13*13/13+11等等,除號和減號最多只可能有兩個,而加號和乘號最多可以為三個;

  至于全排列方法permutation,是借鑒了STL的next_permutation函數(C++),之所以二維數組去重也是封裝的方法可能出現多個數組重復的情況,要知道每多一個數組,底層是用遞歸查詢一遍,瀏覽器會非常卡;

看完這篇關于基于JS如何實現計算24點的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新蔡县| 石屏县| 甘泉县| 巩义市| 东明县| 车致| 德昌县| 遵义县| 榆社县| 修文县| 双江| 昌邑市| 青浦区| 理塘县| 集贤县| 和田县| 阿鲁科尔沁旗| 苗栗县| 赤峰市| 瑞安市| 海阳市| 从化市| 武宣县| 叶城县| 永靖县| 桂平市| 蒲江县| 郴州市| 南召县| 东至县| 太仆寺旗| 汉阴县| 绍兴县| 深州市| 潞西市| 光山县| 华池县| 南丰县| 尼勒克县| 奉贤区| 大冶市|