数字谜题 Java解答
搜索了一番,发现没有Java版的题解,就动手写了一个,应该没什么问题。 为节约时间,有了答案就return了,需要全部答案,可修改 return resultCount + "=" + dpString.get(i);为 System.out.println(resultCount + "=" + dpString.get(i));
public class count {
public static void main(String[] args) throws Exception {
int resultCount = 99;
Object[] nums = {7,7,7,8,8,8,8,9,9,9};
Object[] operators = {"+","+","*","-","-"};
int result = nums.length-operators.length;
if (result<1){
throw new Exception("传入的参数有误,请检查参数");
}
List<Object> operatorList = new ArrayList<>();
for (int i = 0; i < result-1; i++) {
operatorList.add("&");
}
operatorList.addAll(Arrays.asList(operators));
operators = operatorList.toArray();
System.out.println("==============题目===============");
System.out.println(nums.toString());
System.out.println(operators.toString());
System.out.println(resultCount);
System.out.println("==============解答===============");
List<List<Object>> numberSortList = permuteUnique(nums);
List<List<Object>> operatorSortList = permuteUnique(operators);
System.out.println(expression(numberSortList, operatorSortList, resultCount));
}
public static String expression(List<List<Object>> numberSortList,List<List<Object>> operatorSortList,int resultCount){
for (List<Object> numberList : numberSortList) {
for (List<Object> opList : operatorSortList) {
StringBuilder builder = new StringBuilder();
builder.append(numberList.get(0));
for (int i = 0; i < numberList.size() - 1; i++) {
builder.append(opList.get(i));
builder.append(numberList.get(i + 1));
}
String s = builder.toString();
Map<String, Object> map = diffWaysToCompute(s);
List<Long> dp = (List<Long>) map.get("dp");
List<String> dpString = (List<String>) map.get("dpString");
for (int i = 0; i < dp.size(); i++) {
if (dp.get(i) == resultCount) {
return resultCount + "=" + dpString.get(i);
}
}
}
}
return "传入的参数有误,请检查参数";
}
private static boolean[] vis;
public static List<List<Object>> permuteUnique(Object[] nums) {
List<List<Object>> ans = new ArrayList<List<Object>>();
List<Object> perm = new ArrayList<Object>();
vis = new boolean[nums.length];
Arrays.sort(nums);
backtrack(nums, ans, 0, perm);
return ans;
}
public static void backtrack(Object[] nums, List<List<Object>> ans, int idx, List<Object> perm) {
if (idx == nums.length) {
ans.add(new ArrayList<Object>(perm));
return;
}
for (int i = 0; i < nums.length; ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
perm.add(nums[i]);
vis[i] = true;
backtrack(nums, ans, idx + 1, perm);
vis[i] = false;
perm.remove(idx);
}
}
static final long ADDITION = -1;
static final long SUBTRACTION = -2;
static final long MULTIPLICATION = -3;
static final long DIVISION= -4;
static final long AND = -5;
public static Map<String,Object> diffWaysToCompute(String expression) {
List<Long> ops = new ArrayList<Long>();
for (int i = 0; i < expression.length();) {
if (!Character.isDigit(expression.charAt(i))) {
if (expression.charAt(i) == '+') {
ops.add(ADDITION);
} else if (expression.charAt(i) == '-') {
ops.add(SUBTRACTION);
} else if(expression.charAt(i) == '*'){
ops.add(MULTIPLICATION);
} else if(expression.charAt(i) == '/'){
ops.add(DIVISION);
} else if(expression.charAt(i) == '&'){
ops.add(AND);
}
i++;
} else {
long t = 0;
while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
t = t * 10 + expression.charAt(i) - '0';
i++;
}
ops.add(t);
}
}
List<Long>[][] dp = new List[ops.size()][ops.size()];
List<String>[][] dpString = new List[ops.size()][ops.size()];
for (int i = 0; i < ops.size(); i++) {
for (int j = 0; j < ops.size(); j++) {
dp[i][j] = new ArrayList<Long>();
dpString[i][j] = new ArrayList<String>();
}
}
for (int i = 0; i < ops.size(); i += 2) {
dp[i][i].add(ops.get(i));
dpString[i][i].add(ops.get(i).toString());
}
for (int i = 3; i <= ops.size(); i++) {
for (int j = 0; j + i <= ops.size(); j += 2) {
int l = j;
int r = j + i - 1;
for (int k = j + 1; k < r; k += 2) {
List<Long> left = dp[l][k - 1];
List<String> leftString = dpString[l][k - 1];
List<Long> right = dp[k + 1][r];
List<String> rightString = dpString[k + 1][r];
for (int i1 = 0; i1 < left.size(); i1++) {
for (int i2 = 0; i2 < right.size(); i2++) {
if (ops.get(k) == ADDITION) {
if (left.get(i1)==-6||right.get(i2)==-6){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
dp[l][r].add(left.get(i1) + right.get(i2));
dpString[l][r].add("("+leftString.get(i1)+"+"+ rightString.get(i2)+")");
}
} else if (ops.get(k) == SUBTRACTION) {
if (left.get(i1)==-6||right.get(i2)==-6){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
long temp = left.get(i1) - right.get(i2);
if(temp<0){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
dp[l][r].add(temp);
dpString[l][r].add("("+leftString.get(i1)+"-"+ rightString.get(i2)+")");
}
}
} else if (ops.get(k) == MULTIPLICATION) {
if (left.get(i1)==-6||right.get(i2)==-6){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
dp[l][r].add(left.get(i1) * right.get(i2));
dpString[l][r].add("("+leftString.get(i1)+"*"+ rightString.get(i2)+")");
}
} else if (ops.get(k) == DIVISION) {
if (left.get(i1)==-6||right.get(i2)==-6){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
if (right.get(i2)==0||left.get(i1) % right.get(i2)!=0){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
dp[l][r].add(left.get(i1) / right.get(i2));
dpString[l][r].add("("+leftString.get(i1)+"/"+ rightString.get(i2)+")");
}
}
} else if (ops.get(k) == AND) {
if (left.get(i1)==-6||right.get(i2)==-6){
dp[l][r].add(-6L);
dpString[l][r].add("error");
}else {
dp[l][r].add(Long.parseLong(left.get(i1).toString() + right.get(i2).toString()));
dpString[l][r].add("("+leftString.get(i1)+"&"+ rightString.get(i2)+")");
}
}
}
}
}
}
}
Map<String,Object> map = new HashMap();
map.put("dp",dp[0][ops.size() - 1]);
map.put("dpString",dpString[0][ops.size() - 1]);
return map;
}
}