关闭

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

标签: java面试题
703人阅读 评论(0) 收藏 举报
分类:

今天看到一个题目,编写一个在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(expressions.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
0
查看评论

Java HasSet 不保证数据放入后再取出时顺序是一致的

好久没有复习过这样的问题了,过一阵子不看就会忘记,在网上找了一下,看到一个比较有意思的问答,说实话,答题者命中了要害~一起来看看 下面这个是问题,出自thinking in java的一个例子。这哥们做了一个实验,发现输出是有序的,而教材上说HasSet不保证有序,这是什么情况呢? pu...
  • smithdoudou88
  • smithdoudou88
  • 2015-03-12 15:30
  • 564

编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。

前几天遇到这样一个问题:        编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。 刚开始想不出头绪,...
  • youtao271
  • youtao271
  • 2017-08-21 13:41
  • 933

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

import java.util.ArrayList; import java.util.List;   /**  * 1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列, 如:512234、412345等.要求:"4"不能在第三位,&...
  • guonanjun
  • guonanjun
  • 2015-05-14 17:09
  • 2861

C++编程趣题1 在1~9中间填符号使运算结果等于100

在1 2 3 4 5 6 7 8 9九个数字中插入“+”或“-”使其运行得到100
  • Liuchang54
  • Liuchang54
  • 2014-10-12 10:13
  • 3746

把1-9这9个数字按从小到大的顺序排列 ,中间添上“+”和"-"可以计算的结果等于100的程序;

//本题的思路:要在“123456789”中添加加减号,那么可以将它们隔开可以是这样“ 1 2 3 4 5 6 7 8 9”,这样在他们的间隙就有空格(包括最前面的空格)9个,而这些空//格可以填写的内容只有3种情况:1.空,2.“+”3.“-”;这样算复杂度为3^9,用递归的方法实现并保存所有的集...
  • u013790834
  • u013790834
  • 2015-05-21 16:25
  • 4028

编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性

前几天在博客园的外文翻译里看到一篇《每个程序员1小时内必须解决的5个编程问题》,前4题还不是很难,但是第五题就有点看似简单,写起来却很蛋疼。 (虽然头部和其他博文有点相似但是解决办法不太一样,而且好理解) 题目是这样的: 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入...
  • qi923701
  • qi923701
  • 2017-08-24 15:23
  • 562

编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序

编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序。并输出所有的可能性。 /* * 可以看成是在数字中间插入运算符。插入 + - 或空位。那么每个空位有3种选择,加号,减号或者空。 * 一共8个位置,共有3的8次方个情况。每个情况都试一次,找...
  • liufish992
  • liufish992
  • 2015-05-17 11:58
  • 1634

在1,2,…,9(保持这个顺序)之间可任意放+或-或都不放使其结果等于100

需求:写程序在1,2,…,9(保持这个顺序)之间可任意放+或-或都不放使其结果等于100,输出所有可能的放法。例如:1 + 2 + 3 – 4 + 5 + 6 + 78 + 9 = 100。分析:    我们可以理解为有8个位置可以用来放置:“+”、“-”、“”,也就是说表达式的...
  • rlanffy
  • rlanffy
  • 2014-05-29 17:24
  • 1103

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

如题:编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入, 使得计算结果总是100的程序,并输出所有的可能性。 例如:1 + 2 + 34–5 + 67–8 + 9 = 100。 import java.util.Stack; public class Solut...
  • djh122
  • djh122
  • 2015-05-14 10:16
  • 1538

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

微信公众号看到了这样一个面试题:编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性。 例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。 以下是我的解决方案: 思路:先将字符串拆成n个字符串,字符...
  • xxq55
  • xxq55
  • 2017-09-04 09:58
  • 260
    个人资料
    • 访问:2381次
    • 积分:65
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档