一.问题描述:
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求
: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
二.题目分析:
1、输入要生成的组数n。
2、为每组生成4个随机数,存入card集合。
2、穷举每组整数的所有可能计算组合,然后对每个组合求值,把四个数字的运算拆分为为两个数字的运算运算,两个数运算的结果又作为一个新数字和另一个数字进行运算,直至四个数都参与运算。
3.输出所有的满足条件的表达式。
三.流程设计
四.算法实现:
Print类
:
import java.util.ArrayList;
// 输出表达式类
public class Print {
ArrayList<Integer> num = new ArrayList<Integer>();
ArrayList<String> signe = new ArrayList<String>();
// 重载add()方法对集合增加元素
public void add(int n) {
num.add(n);
}
public void add(String str) {
signe.add(str);
}
/**
* 获取运算符的优先级.
* @param s
* @return 返回优先级
*/
public int getPriority(String s) {
if (signe.equals("+"))
return 1;
if (signe.equals("-"))
return 1;
if (signe.equals("*"))
return 2;
if (signe.equals("/"))
return 2;
return -1;
}
/**
* 处理表达式中运算符之间的优先级
* @param la
* @return
*/
public String toString(int la) {
if (la == 0) {
return num.get(0) + signe.get(0) + num.get(1);
} else {
String result = this.toString(la - 1);
//若后面的运算符优先于前面的运算符,前面的表达式带上括号
if (getPriority(signe.get(la)) >= getPriority(signe.get(la - 1)))
result = "(" + result + ")";
result += signe.get(la) + num.get(la + 1);
return result;
}
}
public String toString() {
return toString(2);
}
/**
* 清除集合内的所有内容
*/
public void clear() {
num.clear();
signe.clear();
}
}
deal类
:
import java.util.ArrayList;
public class Deal {
Print experssion = new Print();
/**
* 枚举出所有的表达式
* @param arrayList
* @param number
* @param sum 目标24点
* @return
*/
public boolean count(ArrayList<Integer> arrayList, int number, int sum) {
//集合内为两个数时,穷举6种表达式
if (number == 1) {
if (arrayList.get(0) + arrayList.get(1) == sum) {
experssion.add(arrayList.get(0));
experssion.add(arrayList.get(1));
experssion.add("+");
return true;
}
if (arrayList.get(0) - arrayList.get(1) == sum) {
experssion.add(arrayList.get(0));
experssion.add(arrayList.get(1));
experssion.add("-");
return true;
}
if (arrayList.get(1) - arrayList.get(0) == sum) {
experssion.add(arrayList.get(1));
experssion.add(arrayList.get(0));
experssion.add("-");
return true;
}
if (arrayList.get(0) * arrayList.get(1) == sum) {
experssion.add(arrayList.get(1));
experssion.add(arrayList.get(0));
experssion.add("*");
return true;
}
if (arrayList.get(0) * sum == arrayList.get(1)) {
experssion.add(arrayList.get(0));
experssion.add(arrayList.get(1));
experssion.add("/");
return true;
}
if (arrayList.get(1) * sum == arrayList.get(0)) {
experssion.add(arrayList.get(1));
experssion.add(arrayList.get(0));
experssion.add("/");
return true;
}
return false;
} else {
for (int current = 0; current < arrayList.size(); current++) {
ArrayList<Integer> arrayListTwo = new ArrayList<Integer>();
//currentNum为集合内当前读取的数字
int currentNumber = arrayList.get(current);
for (int i = 0; i < arrayList.size(); i++) {
if (i != currentNumber) {
arrayListTwo.add(arrayList.get(i));
}
}
if (count(arrayListTwo, number - 1, sum - currentNumber)) {
experssion.add("+");
experssion.add(currentNumber);
if (number == 3) {
System.out.println(experssion.toString());
experssion.clear();
}
if (number != 3)
return true;
}
if (count(arrayListTwo, number - 1, sum + currentNumber)) {
experssion.add("-");
experssion.add(currentNumber);
if (number == 3) {
System.out.println(experssion.toString());
experssion.clear();
}
if (number != 3)
return true;
}
if (count(arrayListTwo, number - 1, sum * currentNumber)) {
experssion.add("/");
experssion.add(currentNumber);
if (number == 3) {
System.out.println(experssion.toString());
experssion.clear();
}
if (number != 3)
return true;
}
if (sum % currentNumber == 0) {
if (count(arrayListTwo, number - 1, (int) (sum / currentNumber))) {
experssion.add("*");
experssion.add(currentNumber);
if (number == 3) {
System.out.println(experssion.toString());
experssion.clear();
}
if (number != 3)
return true;
}
}
}
return false;
}
}
}
Main类
:
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Random random =new Random();
Deal deal = new Deal();
//随机生成n种数据求符合要求的表达式
Scanner scanner=new Scanner(System.in);
System.out.println("请输入组数:");
int n=scanner.nextInt();
for(int j=1;j<=n;j++){
ArrayList<Integer> card = new ArrayList<Integer>();
System.out.println("第"+j+"组数据为:");
int t;
for (int i = 0; i < 4; i++) {
t = random.nextInt(13)+1;
card.add(t);
System.out.print(t+" ");
}
System.out.println();
System.out.println("等于24的运算方式为:");
deal.count(card, card.size() - 1, 24);
System.out.println();
}}}
测试:
1、测试用例
:组数等于9.
测试结果如图:
2、测试用例
:组数等于1.
测试结果如图: