【题目背景】
二十四点是一款著名的纸牌游戏,其游戏的目标是使用 3 个加减乘除运算使得 4
张纸牌上数字的运算结果为 24。
【题目描述】
定义每一个游戏由 4 个从 1-9 的数字和 3 个四则运算符组成,保证四则运算符将数字两两隔开,不存在括号和其他字符,运算顺序按照四则运算顺序进行。其中加法用符号 + 表示,减法用符号 - 表示,乘法用小写字母 x 表示,除法用符号 / 表示。在游戏里除法为整除,例如 2 / 3 = 0, 3 / 2 = 1, 4 / 2 = 2。
老师给了你 n 个游戏的解,请你编写程序验证每个游戏的结果是否为 24 。
【数据结构】
该题目中主要用到栈这种先进后出的数据结构计算表达式,大家可以参考课本看看这种数据结构
【实现思路】
二十四点游戏的实质就是表达式求值得过程,在实现过程中采用两个栈,一个为运算符栈opt,另一个为操作数栈num,将一个表达式作为一个字符串输入,依次遍历字符串中的每个字符,如果字符的下标为偶数,说明为数字,其值为数字的字符码-‘0’,并加入num栈,如果为奇数说明为操作符,当操作符栈opt为空时直接入栈,当操作符栈opt不为空时用priority方法比较栈顶元素优先级与当前操作符的优先级,当opt栈顶元素的优先级小于当前操作符的优先级时,当前操作符入栈,当栈顶元素大于当前操作符的优先级时,连续在num栈中pop出两个元素,结合栈顶元素的符号计算出当前两个运算数和运算符的值,将结果加入num栈,最后pop出运算符栈opt的栈顶元素,接下来循环上述------>比较运算符栈opt栈顶元素与当前运算符的优先级,直到opt栈为空或者当前运算符的优先级高于栈顶元素,则结束循环,最后将当前运算符入栈,当表达式扫描完毕后,接着上述opt栈不为空,循环比较优先级,pop两个运算数,一个运算符,由于代码与上面重复,所以封装一个方法numAndOptpop进行上述步骤,这就是详细的思路,上述还有一个方法toSum计算表达式的值,说了这么多直接上代码:
【代码】
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String [] args){
Scanner in = new Scanner(System.in);
Stack<Character> opt = new Stack<>();
Stack<Integer> num = new Stack<>();
int n = in.nextInt();
for (int i=0;i<n;i++){
String s = in.next();
for (int j=0;j<s.length();j++){
if(j%2==0){
num.push((int)s.charAt(j)-'0');
}
else {
if(opt.empty()){
opt.push(s.charAt(j));
}
else{
while(!opt.empty()&&priority(opt.peek(),s.charAt(j))>0){
numAndOptpop(num,opt);
}
opt.push(s.charAt(j));
}
}
}
while(!opt.empty()){
numAndOptpop(num,opt);
}
if(num.peek()==24)
System.out.println("Yes");
else
System.out.println("No");
num.pop();
}
}
public static int toSum(int a,int b,char c){
int sum = 0;
switch (c){
case '+':sum = b+a;break;
case '-':sum = b-a;break;
case 'x':sum = b*a;break;
case '/':sum = b/a;break;
}
return sum;
}
public static int priority(Character a,Character b){
int pro = 1;
if(a=='x'||a=='/'){
pro=1;
}
else {
if(b=='x'||b=='/') {
pro=-1;
}
}
return pro;
}
public static void numAndOptpop(Stack<Integer> num,Stack<Character> opt){
int num1 = num.peek();num.pop();
int num2 = num.peek();num.pop();
num.push(toSum(num1,num2,opt.peek()));
opt.pop();
}
}