将4个大于0 且 小于等于10的整数,通过四则运算得到24。请在控制台中输出给定的4个数字可以得到24的所有组合。
**如:
4 5 6 7 输出
(5+7)*(6-4)
(7-6+5)**4
(7+5-6)*4
…
比较简单的循环遍历写法,用2种线程去跑数据,主要是分为(AB)(CD)和((AB)C)D两种计算的组合方式,分别用2个线程去计算,直接给代码吧:
public class Point24Calculator {
public static void main(String[] args) {
int[] n = {4,5,6,7};//4个数字
CountDownLatch count = new CountDownLatch(2);
long start = System.currentTimeMillis();
Point24Calculator twenty = new Point24Calculator();
//构建2种数字组合方式的线程
Thread1 thread1 = twenty.new Thread1(n, count);
Thread2 thread2 = twenty.new Thread2(n, count);
thread1.run();
thread2.run();
try {
count.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
}
//线程1 实现(A i B) k (C j D)类型计算 i,j,k为运算符(+ - * /)
class Thread1 implements Runnable {
int[] n;
CountDownLatch count;
Map<String, String> map = new HashMap<String, String>() {
{
put("0", "+");
put("1", "-");
put("2", "*");
put("3", "/");
}
};
//取4个数中,剩下的2个数
public int[] getLeft(int num1, int num2) {
int[] n = new int[2];
int temp = 0;
Queue<Integer> queue = new ArrayBlockingQueue<Integer>(4);
for (int i = 0; i < 4; i++) queue.add(i);
for (int i = 0; i < 4; i++) {
int num = queue.poll();
if (num != num1 && num != num2) {
n[temp++] = num;
}
}
return n;
}
//将计算符号转化为具体的计算结果
int math(int n1, int n2, String c) {
switch (c) {
case "+":
return n1+n2;
case "-":
return n1 - n2;
case "*":
return n1 * n2;
case "/":
//计算异常,返回Integer.MAX_VALUE
if (n2 == 0) {
return Integer.MAX_VALUE;
}
if (n1 % n2 != 0) {
return Integer.MAX_VALUE;
}
return n1 / n2;
default:
return 0;
}
}
public Thread1(int[] n, CountDownLatch count) {
this.n = n;
this.count = count;
}
public void init(List<int[]> list) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
//跳过取相同的值
if (i == j) continue;
//A B C D的赋值,
int[] num = new int[4];
num[0] = n[i];
num[1] = n[j];
//C D 两种取值之1
num[2] = n[getLeft(i, j)[0]];
num[3] = n[getLeft(i, j)[1]];
list.add(num);
int[] num2 = new int[4];
num2[0] = n[i];
num2[1] = n[j];
//C D 两种取值之2
num2[2] = n[getLeft(i, j)[1]];
num2[3] = n[getLeft(i, j)[0]];
list.add(num2);
}
}
}
@Override
public void run() {
// (A B)(C D)组合
List<int[]> list = new ArrayList<>();
init(list);
for (int ii = 0; ii < list.size(); ii++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
//(A i B) k (C j D) i,j,k为运算符(+ - * /)
int[] num = list.get(ii);
int A = math(num[0], num[1], map.get(i + ""));
int B = math(num[2], num[3], map.get(j + ""));
int C = math(A, B, map.get(k + ""));
//如果返回为Integer.MAX_VALUE,则表示计算异常,contine
if (A == Integer.MAX_VALUE || B == Integer.MAX_VALUE ||
C == Integer.MAX_VALUE) continue;
if ((C) == 24) {
System.out.println("(" + num[0] + map.get(i + "") + num[1] + ")" +
map.get(k + "") + "(" + num[2] + map.get(j + "") + num[3] + ")");
}
}
}
}
}
count.countDown();
}
}
//继承线程1,具体不同实现方法在run, 实现((A i B) k C) j D)类型计算 i,j,k为运算符(+ - * /)
class Thread2 extends Thread1 {
public Thread2(int[] n, CountDownLatch count) {
super(n, count);
}
@Override
public void run() {
// ((A B) C) D)组合
List<int[]> list = new ArrayList<>();
super.init(list);
for (int ii = 0; ii < list.size(); ii++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
//((A i B) k C) j D) i,j,k为运算符(+ - * /)
int[] num = list.get(ii);
int A = math(num[0], num[1], map.get(i + ""));
int B = math(A, num[2], map.get(k + ""));
int C = math(B, num[3], map.get(j + ""));
//如果返回为Integer.MAX_VALUE,则表示计算异常,contine
if (A == Integer.MAX_VALUE || B == Integer.MAX_VALUE || C == Integer.MAX_VALUE) continue;
if ((C) == 24) {
System.out.println("((" + num[0] + map.get(i + "")
+ num[1] + ")" + map.get(k + "") + num[2] + ")" + map.get(j + "") + num[3]);
}
}
}
}
}
count.countDown();
}
}
}