计算 24 点 游戏:
任意 输入 4 个数字,进行计算,判断结果能否等于 24.
若 有,则 具体的 输出表达式
这里的计算 24 点,有两种形式
下面式子中 * 可能是 + - * /
第一种: (a * ( b * ( c * d )))
第二种: (a * b)+ ( c * d ) 或 (a * b)- ( c * d )
import java.util.Arrays;
import java.util.HashSet; //实现 Set接口,由 哈希表支持。使用HashSet类创建Set集合对象,然后调用add方法为Set集合添加内容。
import java.util.Iterator; //迭代器,通过 遍历,能得到集合类 中的内容。
import java.util.Scanner;
public class calculate_twfour_points {
/*
这是java对态的一种表现,有时候可能不知道子类需要何种类型而声明一个接口.以后类似
Set<String> setStr=new HashSet<String>();这种声明 其实SetStr是HashSet类型(虽然声明时为Set,但JVM
运行时回自动把他转化为HashSet类型的),这种做法就更能体现接口的意义了.
*/
private static HashSet<String> set = new HashSet<String>();
public static void main(String[] args) {
int nums[] = new int[4];
Scanner sc = new Scanner(System.in);
System.out.println(" 请输入 4 个数字:");
for (int i = 0; i < 4; i++) {
nums[i] = sc.nextInt();
}
System.out.println(" 计算 24 点的结果如下:");
total(nums);
print(set);
/*
这是一组 用于测试 用的 数据
// int[] nums = {5, 5, 5, 1};
// int[]nums = {3,3,8,8}; *** 、、、
// int[]nums ={3,4,4,9}; ***
// int[] nums = {4, 6, 9, 11};***
// int[]nums ={2,2,7,9};***
// int[]nums = {4, 5, 7, 8};
// int[]nums={3,4,6,9};
// int[]nums={3,4,5,10};
*/
}
public static void total(int[] nums) {
Arrays.sort(nums); //对数组进行从小到大排序,默认字典序排序(ASCII)
int count = equalsCount(nums); //统计 4 个数,有几个相同的
int a = nums[0];
int b = nums[1];
int c = nums[2];
int d = nums[3];
if (count == 0) { //a b c d ,4个数各不相同
main(new int[]{a, b, c, d}); //计算 这 4 个数,能否实现24点
main(new int[]{a, b, d, c});
main(new int[]{a, c, b, d});
main(new int[]{a, c, d, b});
main(new int[]{a, d, b, c});
main(new int[]{a, d, c, b});
main(new int[]{b, c, d, a});
main(new int[]{b, c, a, d});
main(new int[]{b, d, a, c});
main(new int[]{b, d, c, a});
main(new int[]{b, a, c, d});
main(new int[]{b, a, d, c});
main(new int[]{c, d, a, b});
main(new int[]{c, d, b, a});
main(new int[]{c, a, b, d});
main(new int[]{c, a, d, b});
main(new int[]{c, b, a, d});
main(new int[]{c, b, d, a});
} else if (count == 1) { //a a b c
int m = 0;//相同
int p = 0;
int q = 0;
if (a == b) {
m = a;
p = c;
q = d;
main(new int[]{m, m, p, q});
main(new int[]{m, m, q, p});
} else if (b == c) {
m = b;
p = a;
q = d;
main(new int[]{p, m, m, q});
main(new int[]{q, m, m, p});
} else if (c == d) {
m = c;
p = a;
q = b;
main(new int[]{p, q, m, m});
main(new int[]{q, p, m, m});
}
} else if (count == 4) { //a a b b 这4个数 与 a a a b 在计算count时 是同一个值 2
int m = a;
int n = c;
main(new int[]{m, m, n, n});
main(new int[]{n, n, m, m});
main(new int[]{m, n, m, n});
main(new int[]{n, m, n, m});
} else if (count == 2) { // a a a b 有3 个数相同
int m = 0;//相同的
int n = 0;//单独的
if (a == b) {
m = a;
n = d;
} else if (c == d) {
m = d;
n = a;
}
main(new int[]{m, m, m, n});
main(new int[]{m, m, n, m});
main(new int[]{m, n, m, m});
main(new int[]{n, m, m, m});
} else if (count == 3) { //a a a a 四个数相同
main(new int[]{a, b, c, d});
}
}
///
///
public static int equalsCount(int nums[]) { //统计 4 个数,有几个相同的
int count = 0;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]) {
count++;
}
}
if (count == 2) { // 要对 4个数是 a a a b 型 和 a a b b 型 进行区分
if (nums[1] == nums[2]) { //a a b b 型
return 2;
} else //a a a c 型 ,因为前面进行 排过序了
return 4;
}
return count;
}
public static void main(int nums[]) { //实现 计算 24 点 的 函数
double a = nums[0];
double b = nums[1];
double c = nums[2];
double d = nums[3];
double sum = 0;
double sumad1 = 0;
double sumad2 = 0;
double sumad3 = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
sum = calculate(calculate(calculate(a, b, i), c, j), d, k); //递归 遍历计算
sumad1 = calculate(calculate(a, b, i), calculate(c, d, j), k);
sumad2 = calculate(calculate(a, c, i), calculate(b, d, j), k);
sumad3 = calculate(calculate(a, d, i), calculate(b, c, j), k);
if (sum > 23.999999999 && sum < 24.00000001) { // sum 是浮点型,不能用 sum ==24.0 ,比如 3 3 8 8 就计算不出来
set.add(format(i, j, k, a, b, c, d)); //使用HashSet类创建Set集合对象,然后调用add方法为Set集合添加内容。
}
if (sumad1 > 23.999999999 && sumad1 < 24.00000001) {
System.out.println(sumad1);
System.out.println(format( a, b, c, d, i, j, k));
}
if (sumad2 > 23.999999999 && sumad2 < 24.00000001) {
System.out.println(sumad2);
System.out.println(format( a, b, c, d, i, j, k));
}
if (sumad3 > 23.999999999 && sumad3 < 24.00000001) {
System.out.println(sumad3);
System.out.println(format( a, b, c, d, i, j, k));
}
}
}
}
}
/************************************************************************************************************
***********************************************************************************************************/
/**
这个 format 函数 和 下面 还有一个 format 函数 是不同的。
此处的 用于 显示 第二种 形式的 表达式。
*/
private static StringBuilder format(double a, double b, double c, double d, int i, int j, int k) {
StringBuilder sb = new StringBuilder(); // new 的StringBuilder 去构造的字符串
if ((i == 2 || i == 5) && (j == 2 || j == 5) && (k == 2 || k == 5)) {
sb.append('(');
sb.append(d);
sb.append(symbol(j));
sb.append(c);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(b);
sb.append(symbol(i));
sb.append(a);
sb.append(')');
}
if ((i == 2 || i == 5) && (j == 2 || j == 5) && (k != 2 && k != 5)) {
//System.out.println( '(' + b + symbol(i) + a + ')'+ symbol(k) +'(' + d + symbol(j) + c + ')');
sb.append('(');
sb.append(b);
sb.append(symbol(i));
sb.append(a);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(d);
sb.append(symbol(j));
sb.append(c);
sb.append(')');
}
if ((i == 2 || i == 5) && (k == 2 || k == 5) && (j != 2 && j != 5)) {
//System.out.println( '(' + c + symbol(j) + d + ')'+ symbol(k) +'(' + b + symbol(i) + a + ')');
sb.append('(');
sb.append(c);
sb.append(symbol(j));
sb.append(d);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(b);
sb.append(symbol(i));
sb.append(a);
sb.append(')');
}
if ((j == 2 || j == 5) && (k == 2 || k == 5) && (i != 2 && i != 5)) {
//System.out.println( '(' + d + symbol(j) + c + ')'+ symbol(k) +'(' + a + symbol(i) + b + ')');
sb.append('(');
sb.append(d);
sb.append(symbol(j));
sb.append(c);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(a);
sb.append(symbol(i));
sb.append(b);
sb.append(')');
}
if ((i == 2 || i == 5) && (j != 2 && j != 5) && (k != 2 && k != 5)) {
//System.out.println( '(' + b + symbol(i) + a + ')'+ symbol(k) +'(' + c + symbol(j) + d + ')');
sb.append('(');
sb.append(b);
sb.append(symbol(i));
sb.append(a);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(c);
sb.append(symbol(j));
sb.append(d);
sb.append(')');
}
if ((j == 2 || j == 5) && (i != 2 && i != 5) && (k != 2 && k != 5)) {
//System.out.println( '(' + a + symbol(i) + b + ')'+ symbol(k) +'(' + d + symbol(j) + c + ')');
sb.append('(');
sb.append(a);
sb.append(symbol(i));
sb.append(b);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(d);
sb.append(symbol(j));
sb.append(c);
sb.append(')');
}
if ((k == 2 || k == 5) && (i != 2 && i != 5) && (j != 2 && j != 5)) {
//System.out.println( '(' + c + symbol(j) + d + ')'+ symbol(k) +'(' + a + symbol(i) + b + ')');
sb.append('(');
sb.append(c);
sb.append(symbol(j));
sb.append(d);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(a);
sb.append(symbol(i));
sb.append(b);
sb.append(')');
}
if ((i != 2 && i != 5) && (j != 2 && j != 5) && (k != 2 && k != 5)) {
sb.append('(');
sb.append(a);
sb.append(symbol(i));
sb.append(b);
sb.append(')');
sb.append(symbol(k));
sb.append('(');
sb.append(c);
sb.append(symbol(j));
sb.append(d);
sb.append(')');
}
return sb;
}
/**
symbol 是符号的意思
*/
public static char symbol(int n) {
switch (n) {
case 0:
return '+';
case 1:
return '-';
case 2:
return '-';
case 3:
return '*';
case 4:
return '/';
case 5:
return '/';
default:
throw new RuntimeException("--Wrong!!!!!--");
}
}
/***************************************************************************************************************/
/************************************************************************************************************
***********************************************************************************************************/
public static double calculate(double a, double b, int n) { //每次 每2个数 进行计算
switch (n) {
case 0:
return a + b;
case 1:
return a - b;
case 2:
return b - a;
case 3:
return a * b;
case 4:
return a / b;
case 5:
return b / a;
default:
throw new RuntimeException("--Wrong!!!!!--");
/*
提示调用者该功能尚未实现,Wrong只是留了个接口,并未真正实现功能。 RuntimeException属于运行异常,
抛出来所以调用它的函数就不需要处理异常了。抛异常后下面就不执行了,所以不用写返回值
*/
}
}
///
///
/**
* 下面 函数 用于输出 显示 第 一 种 形式的 公式
*/
public static String format(int i, int j, int k, double a, double b, double c, double d) { //使用 String.format() 这个方法连接字符串
StringBuilder sb = new StringBuilder();
sb.append(format(format(format(new StringBuilder(valueOf(a)), new StringBuilder(valueOf(b)), i), new StringBuilder(valueOf(c)), j), new StringBuilder(valueOf(d)), k));
return sb.toString();
}
private static String valueOf(double b) { // 返回 double 参数的 字符串 表示形式。
String result = String.valueOf(b);
if (result.endsWith(".0")) {
return result.substring(0, result.length() - 2);
}
return result;
}
private static StringBuilder format(StringBuilder a, StringBuilder b, int n) {
StringBuilder sb = new StringBuilder(); // new 的StringBuilder 去构造的字符串
switch (n) {
case 0: // ( a + b )
sb.append('('); //意思是在字符串 sb 末尾添加上 '(' ,在对字符串有多个拼接字符串操作的时候效率比string高。
sb.append(a);
sb.append('+');
sb.append(b);
sb.append(')');
return sb;
case 1:
sb.append('('); // ( a - b )
sb.append(a);
sb.append('-');
sb.append(b);
sb.append(')');
return sb;
case 2: // ( b - a )
sb.append('(');
sb.append(b);
sb.append('-');
sb.append(a);
sb.append(')');
return sb;
case 3: // a * b
sb.append(a);
sb.append('*');
sb.append(b);
return sb;
case 4: // ( a / b )
sb.append('(');
sb.append(a);
sb.append('/');
sb.append(b);
sb.append(')');
return sb;
case 5: // ( b / a )
sb.append('(');
sb.append(b);
sb.append('/');
sb.append(a);
sb.append(')');
return sb;
default:
throw new RuntimeException("--Wrong!!!!!--");
}
}
private static void print(HashSet<String> set) {
if (set.size() == 0) {
System.out.println("形式 2 无解");
return;
}
Iterator<String> ite = set.iterator();
while (ite.hasNext()) {
String str = ite.next();
System.out.println(str);
}
}
}