您的位置:首页 > 编程语言 > Java开发

用java编写在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100

2017-08-22 15:22 525 查看
今天看到一个题目,编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。

刚开始看到题目的时候一筹莫展,但是题目下一条留言点拨了我:+、-和不插入可以对应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的效率提高了两个数量级,几十毫秒就执行完了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐