前言
休息的时候无意间看到群里有人发出了华为的校招题,一开始看题目的时候觉得很简单,于是晚上就试着写了一下,结果写的过程中打脸,不断的整理逻辑不断的重写,但我的性格又是不做出来晚上睡不好的那种,于是在做出来的时候就分享给大家(快凌晨三点了有木有,这校招题难度都达到这级别了?o(╥﹏╥)o)
题目描述
审题要注意: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)} ${d} = ${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>
实现的效果:
总结思路:
题目第一眼看到就应该想到递归,之前我是把加减乘除都设为一个方法,想采用面向切面的方式进行计算,但是这种方式逻辑复杂且无法计算复杂一点的公式,因此就改为直接把所有可能出现的结果都拿出来一一比对,只要其中一个为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++),之所以二维数组去重也是封装的方法可能出现多个数组重复的情况,要知道每多一个数组,底层是用递归查询一遍,浏览器会非常卡;
最后就是我在代码中提到的优化方法,有兴趣的小伙伴可以去试一下,代码还有优化的空间。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]