用java编写在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100
2017-08-22 15:22
1186 查看
今天看到一个题目,编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。
刚开始看到题目的时候一筹莫展,但是题目下一条留言点拨了我:+、-和不插入可以对应2、1和0这三个数字,1到9之间有8个空位,所以有3的8次方种可能性,即6561种组合。8位3进制数正好对应这些排列组合。
使用javax.script包中的计算类,可以运行字符串算术表达式得到计算结果
这种实现方法思路简单,代码少,缺点是计算速度比较慢。
慢的原因主要是ScriptEngine类运算算数表达式的效率比较低,鉴于我们这里用到的算数表达式只有比较简单的加减运算,我们可以自己写一个简单的加减算数表达式计算方法:
使用这个方法替代ScriptEngine.eval可以大幅提高效率,下面贴出完整的代码:
比之前使用ScriptEngine.eval的效率提高了两个数量级,几十毫秒就执行完了
刚开始看到题目的时候一筹莫展,但是题目下一条留言点拨了我:+、-和不插入可以对应2、1和0这三个数字,1到9之间有8个空位,所以有3的8次方种可能性,即6561种组合。8位3进制数正好对应这些排列组合。
有了思路之后使用Java实现:
先写一个进制转换的方法:/** * 实现将十进制数num转换成radix进制数 * * @param num * 十进制数 * @param radix * 进制 * @return 转换后的数 */ public static String radixConvert(int num, int radix) { StringBuilder sb = new StringBuilder(); boolean flag = false; // 正负标记 if (num == 0) { return "0"; } else if (num < 0) { num = num * -1; flag = true; } while (num > 0) { int m = num % radix; num = num / radix; sb.append(m); } if (flag) { sb.append("-"); } // 倒叙输出字符串 return sb.reverse().toString(); }
使用javax.script包中的计算类,可以运行字符串算术表达式得到计算结果
Map<Character, String> map = new HashMap<>(); map.put('0', ""); map.put('1', "-"); map.put('2', "+"); // javax.script包提供的运算类,可以计算字符串算术表达式得到运算结果 ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); String str = null; StringBuilder expressions = null; for (int i = 0; i < 6561; i++) { // 将数字转换为8位3进制 str = "0000000" + radixConvert(i, 3); str = str.substring(str.length() - 8); // 算术表达式以1开头 expressions = new StringBuilder("1"); for (int j = 0; j < 8; j++) { expressions.append(map.get(str.charAt(j))).append(j + 2); } // 得到运算结果 int result = (int) engine.eval(ex b64b pressions.toString()); if (result == 100) { System.out.println(expressions.toString()); } }
最后得到的结果是: 123-45-67+89 123-4-5-6-7+8-9 123+45-67+8-9 123+4-5+67-89 12-3-4+5-6+7+89 12+3-4+5+67+8+9 12+3+4+5-6-7+89 1+23-4+56+7+8+9 1+23-4+5+6+78-9 1+2+34-5+67-8+9 1+2+3-4+5+6+78+9 共11种。
这种实现方法思路简单,代码少,缺点是计算速度比较慢。
慢的原因主要是ScriptEngine类运算算数表达式的效率比较低,鉴于我们这里用到的算数表达式只有比较简单的加减运算,我们可以自己写一个简单的加减算数表达式计算方法:
/** * 运算简单的加减算数表达式 * * @param expressions * 算数表达式 * @return */ public static int simpleEval(String expressions) { int tempIndex = 0; List<Integer> numberList = new ArrayList<>(); // 数字列表 List<Character> operatorList = new ArrayList<>(); // 运算符列表 for (int i = 0; i < expressions.length(); i++) { if (expressions.charAt(i) == '+' || expressions.charAt(i) == '-') { numberList.add(Integer.parseInt(expressions.substring(tempIndex, i))); operatorList.add(expressions.charAt(i)); tempIndex = i + 1; } } // 当表达式里没有运算符,即表达式为一个数字,直接输出 if (operatorList.size() == 0) { return Integer.parseInt(expressions); } // 把最后一个运算符后的数字加入数字列表 if (tempIndex < expressions.length()) { numberList.add(Integer.parseInt(expressions.substring(tempIndex, expressions.length()))); } // 计算结果 int result = numberList.get(0); for (int i = 0; i < operatorList.size(); i++) { if (operatorList.get(i) == '+') { result = result + numberList.get(i + 1); } else if (operatorList.get(i) == '-') { result = result - numberList.get(i + 1); } } return result; }
使用这个方法替代ScriptEngine.eval可以大幅提高效率,下面贴出完整的代码:
public static void main(String[] args) { Map<Character, String> map = new HashMap<>(); map.put('0', ""); map.put('1', "-"); map.put('2', "+"); String str = null; StringBuilder expressions = null; for (int i = 0; i < 6561; i++) { // 将数字转换为8位3进制 str = "0000000" + radixConvert(i, 3); str = str.substring(str.length() - 8); // 算术表达式以1开头 expressions = new StringBuilder("1"); for (int j = 0; j < 8; j++) { expressions.append(map.get(str.charAt(j))).append(j + 2); } // 得到运算结果 int result = simpleEval(expressions.toString()); if (result == 100) { System.out.println(expressions.toString()); } } } /** * 运算简单的加减算数表达式 * * @param expressions * 算数表达式 * @return */ public static int simpleEval(String expressions) { int tempIndex = 0; List<Integer> numberList = new ArrayList<>(); // 数字列表 List<Character> operatorList = new ArrayList<>(); // 运算符列表 for (int i = 0; i < expressions.length(); i++) { if (expressions.charAt(i) == '+' || expressions.charAt(i) == '-') { numberList.add(Integer.parseInt(expressions.substring(tempIndex, i))); operatorList.add(expressions.charAt(i)); tempIndex = i + 1; } } // 当表达式里没有运算符,即表达式为一个数字,直接输出 if (operatorList.size() == 0) { return Integer.parseInt(expressions); } // 把最后一个运算符后的数字加入数字列表 if (tempIndex < expressions.length()) { numberList.add(Integer.parseInt(expressions.substring(tempIndex, expressions.length()))); } // 计算结果 int result = numberList.get(0); for (int i = 0; i < operatorList.size(); i++) { if (operatorList.get(i) == '+') { result = result + numberList.get(i + 1); } else if (operatorList.get(i) == '-') { result = result - numberList.get(i + 1); } } return result; } /** * 实现将十进制数num转换成radix进制数 * * @param num * 十进制数 * @param radix * 进制 * @return 转换后的数 */ public static String radixConvert(int num, int radix) { StringBuilder sb = new StringBuilder(); boolean flag = false; // 正负标记 if (num == 0) { return "0"; } else if (num < 0) { num = num * -1; flag = true; } while (num > 0) { int m = num % radix; num = num / radix; sb.append(m); } if (flag) { sb.append("-"); } // 倒叙输出字符串 return sb.reverse().toString(); }
比之前使用ScriptEngine.eval的效率提高了两个数量级,几十毫秒就执行完了
相关文章推荐
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34–5 + 67–8 + 9 = 100。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性。 例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100
- 文章标题编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序
- (scala实现) 在1到9(顺序不能变)之间插入+或-或什么都不插入,使得计算结果总是100
- 编写程序输出1到100之间出现数字9的所有数字
- 输入一个表达式,没有括号,数字小于0-9之间,输出计算结果,所有的中间结果化为整形。 例如: 输入:3+8×2/9-2 输出:2
- 输入一个表达式,没有括号,数字小于0-9之间,输出计算结果,所有的中间结果化为整形。 例如: 输入:3+8×2/9-2 输出:2
- 输入一个表达式,没有括号,数字小于0-9之间,输出计算结果,所有的中间结果化为整形。 例如: 输入:3+8×2/9-2 输出:2
- 输出一个整数的每一位,计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,编写程序数一下 1到 100 的所有整数中出现多少次数字 9
- 编写一个java程序,从1加到100,每做一次加法,就休眠1秒,当程序运行过程中,杀死这个程序。 再次运行,还能从上次的计算结果继续下去