每个程序员1小时内必须解决的5个编程问题 - 个人答题

来源:互联网 发布:vr头显 知乎 封闭式 编辑:程序博客网 时间:2024/06/06 02:58

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">2015.05.10在SCDN中看到了一篇《每个程序员1小时内必须解决的5个编程问题》的博文</span>

问题如下:

问题1:使用for循环、while循环和递归写出3个函数来计算给定数列的总和。

问题2:编写一个交错合并列表元素的函数。例如:给定的两个列表为[a,B,C]和[1,2,3],函数返回[a,1,B,2,C,3]。

问题3:编写一个计算前100位斐波那契数的函数。根据定义,斐波那契序列的前两位数字是0和1,随后的每个数字是前两个数字的和。

例如,前10位斐波那契数为:0,1,1,2,3,5,8,13,21,34。

问题4:编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[50,2,1,9],最大数字为95021。

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

例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。


以下是我个人的解题方法,并不是标准解法,如果有更好的解法或者方案,欢迎大家留言,一起进步。


package imeng.onehour;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;import javax.script.ScriptException;/** * 类说明:每个程序员1小时内必须解决的5个编程问题<br> * 问题1:<br> * 使用for循环、while循环和递归写出3个函数来计算给定数列的总和。<br> * 问题2:<br> * 编写一个交错合并列表元素的函数。<br> * 例如:给定的两个列表为[a,B,C]和[1,2,3],函数返回[a,1,B,2,C,3]。<br> * 问题3:<br> * 编写一个计算前100位斐波那契数的函数。<br> * 根据定义,斐波那契序列的前两位数字是0和1,随后的每个数字是前两个数字的和。<br> * 例如,前10位斐波那契数为:0,1,1,2,3,5,8,13,21,34。<br> * 问题4:<br> * 编写一个能将给定非负整数列表中的数字排列成最大数字的函数。<br> *例如,给定[50,2,1,9],最大数字为95021。<br> * 问题5:<br> *编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入, *使得计算结果总是100的程序,并输出所有的可能性。<br> *例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。 * @author IMeng */public class Question {/** * 方法说明:main函数,默认类运行函数 * @param args */public static void main(String[] args) {doQuestion01();doQuestion02();doQuestion03();doQuestion04();doQuestion05();}/** * 方法说明: * 使用for循环、while循环和递归写出3个函数来计算给定数列的总和。<br> */public static void doQuestion01(){int[] param = {1,2,3,4,5,6,7,8,9};System.out.println("FOR循环的答案:"+doInForLoop(param));System.out.println("WHILE循环的答案:"+doInWhileLoop(param));System.out.println("SELF循环的答案:"+doInSlefLoop(0, param));}/** * 方法说明: *编写一个交错合并列表元素的函数。<br>  * 例如:给定的两个列表为[a,B,C]和[1,2,3],函数返回[a,1,B,2,C,3]。<br> */public static void doQuestion02(){char[] charParam = {'a','B','C'};int[] intParam = {1,2,3};List<Object> result = new ArrayList<Object>(6);for (int i = 0; i < charParam.length; i++) {result.add(charParam[i]);for (int j = 0; j < intParam.length; j++) {if( i == j ){result.add(intParam[j]);}}}for (Object object : result) {System.out.println(object);}}/** * 方法说明: * 编写一个计算前100位斐波那契数的函数。<br> * 根据定义,斐波那契序列的前两位数字是0和1,随后的每个数字是前两个数字的和。<br> * 例如,前10位斐波那契数为:0,1,1,2,3,5,8,13,21,34。<br> */public static void doQuestion03(){int num = 100;long preNum = 0;long curNum = 1;long temNum = 0;System.out.println("第 1 位斐波那契数:" + preNum);System.out.println("第 2 位斐波那契数:" + curNum);for (int i = 0; i < num; i++) {temNum = curNum;curNum += preNum;preNum = temNum;System.out.println("第 "+ (i+2) +" 位斐波那契数:" + curNum);i++;}}/** * 方法说明: * 编写一个能将给定非负整数列表中的数字排列成最大数字的函数。<br> * 例如,给定[50, 2, 1, 889, 88, 878, 8, 100],最大数字为9995021。<br> *  * 思路解析:<br> * 1、自定义一个list保存数组中的数字<br> * 2、外层遍历数组,注意是数组,而不是我们自定义的list<br> * 3、内层遍历list,找出list中最大的数<br> *  * 接下来就是内层遍历核心思路:<br> * 先抛出问题:<br> * 3.1、50和9比较,我们要的是9<br> * 3.2、重复的数字<br> * 3.3、89和8的比较,87和8的比较 *  * 我的解决思路:<br> * ->3.1 将数字转成字符串,比较字符串长度,取小设为minLength; * 然后截取字符串长度就是minLength,再转成数字比较即可<br> * ->3.2 外层遍历一次就可以取出一个最大值,然后直接在内容循环外部删除当前最大值即可<br> * ->3.3 如果长度不同,但是截取后数字一样大,将较大数的从左到右截取相差位数补到较小数后面 * 89和8比较,就是89和88比较;878和8比较,就是878和887比较 */public static void doQuestion04(){Integer[] param = { 50, 2, 1, 889, 88, 878, 8, 100 };// 使用Arrays.asList得到的是一个固定大小的列表,可以看方法说明// 跟踪到源代码,你会发现得到的是java.util.Arrays.ArrayList// 继承AbstractList,实现RandomAccess, java.io.SerializableList<Integer> arraysArrayList = Arrays.asList(param);System.out.println("使用Arrays.asList得到的列表的类:"+ arraysArrayList.getClass());// new ArrayList()得到的是java.util.ArrayList.ArrayList// 与java.util.Arrays.ArrayList不同的是// java.util.ArrayList.ArrayList实现了List接口中方法List<Integer> utilArrayList = new ArrayList<Integer>();System.out.println("使用new ArrayList<T>()得到的列表的类:" + utilArrayList.getClass());for (Integer integer : param) {utilArrayList.add(integer);}int max = -1;String maxNumStr = "";for (int i = 0; i < param.length; i++) {max = -1;// 取出最大的数for (int num : utilArrayList) {if( max  == -1){max = num;}else{String curStr = String.valueOf(num),// 当前数字转成字符串<span style="white-space:pre"></span>maxStr = String.valueOf(max);// 目前最大数字转成字符串<span style="white-space:pre"></span><span style="white-space:pre"></span>// 更简单的思路:直接将两个数字转成字符串,然后对接比较大小<span style="white-space:pre"></span>long curLon = Long.valueOf(curStr + maxStr);<span style="white-space:pre"></span>long maxLon = Long.valueOf(maxStr + curStr);<span style="white-space:pre"></span>if(curLon > maxLon){<span style="white-space:pre"></span>max = num;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>// FIXME  此方法不行,给定数组{43,43434},按此方法均可,实际4343443比4343434大//<span style="white-space:pre"></span>int curStrLength = curStr.length(),// 当前数字长度//<span style="white-space:pre"></span>maxStrLength = maxStr.length(),// 目1前最大数字长度//<span style="white-space:pre"></span>minLength = curStrLength < maxStrLength ? curStrLength : maxStrLength;//<span style="white-space:pre"></span>int curNum = Integer.valueOf(curStr.substring(0, minLength)),//<span style="white-space:pre"></span>maxNum = Integer.valueOf(maxStr.substring(0, minLength));//<span style="white-space:pre"></span>if(maxNum == curNum){// 3.3情况,截取后的大小一样//<span style="white-space:pre"></span>// 这个情况,直接把两个数字对接比较大小//<span style="white-space:pre"></span>curStr = curStr + maxStr;//<span style="white-space:pre"></span>maxStr = maxStr + curStr;//<span style="white-space:pre"></span>//<span style="white-space:pre"></span>long curLon = Long.valueOf(curStr);//<span style="white-space:pre"></span>long maxLon = Long.valueOf(maxStr);//<span style="white-space:pre"></span>if(curLon > maxLon){//<span style="white-space:pre"></span>//<span style="white-space:pre"></span>}//<span style="white-space:pre"></span>if(curStrLength < maxStrLength){//<span style="white-space:pre"></span>curStr += maxStr.substring(0, maxStrLength - minLength);//<span style="white-space:pre"></span>}else{//<span style="white-space:pre"></span>maxStr += curStr.substring(0, curStrLength - minLength);//<span style="white-space:pre"></span>}//<span style="white-space:pre"></span>}else{//<span style="white-space:pre"></span>max = maxNum > curNum ? max : num;//<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}}maxNumStr += max;int index = 0;for (index = 0; index < arraysArrayList.size(); index++) {if(utilArrayList.get(index) == max){break;}}utilArrayList.remove(index);}System.out.println("最大数字为:"+ maxNumStr);}/** * 方法说明:<br> * 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入, *使得计算结果总是100的程序,并输出所有的可能性。<br> *例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。<br> * 思路解析:<br> * 1、通过递归求出所有的排列组合,为3的8次方 =  6561次<br> *  2、根据组合,和数字的结合,求出各种情况的等式<br> *  3、利用JS中eval的方法求出等式的值,输出满足条件的等式。 */public static void doQuestion05(){char[] combination = new char[8];getCombination(0, combination);}/** * 方法说明:for循环 * @param param * @return */private static int doInForLoop(int[] param){int sum = 0;for (int i : param) {sum += i;}return sum;}/** * 方法说明:while循环 * @param param * @return */private static int doInWhileLoop(int[] param){int current = 0 ;int sum = 0;while(current < param.length){sum += param[current];current++;}return sum;}/** * 方法说明:递归算法 * @param current * @param param * @return */private static int doInSlefLoop(int current, int[] param){if(current < param.length - 1){return param[current] + doInSlefLoop(++current, param);}else{return param[current];}}/** * 方法说明:实现排列组合<br> * 逻辑剖析: * 1、从最后的一位数开始组合, * @param index * @param combination */private static void getCombination(int index, char[] combination){char[] option = { '+', '-', ' ' };if(index == 8){// 已经全部组合完毕getResult(combination);}else{for (char c : option) {combination[index] = c;getCombination(index+1, combination);}}}/** * 方法说明:根据组合得到等式,并对等式进行计算,输出符合的等式 * @param combination * @throws ScriptException  */private static void getResult(char[] combination) {int[] num = { 1,2,3,4,5,6,7,8,9 };StringBuilder temSB = new StringBuilder();for ( int i = 0; i < num.length; i++ ) {if( i > 0 && combination[i-1] != ' '){temSB.append(combination[i-1]);}temSB.append(num[i]);}if(doCal(temSB) == 100){System.out.println(temSB.toString() + " = 100");}}/**  * 方法说明:利用js中的eval方法进行计算 * @param sb 含有等式的字符串 * @return 翻译计算结果 */private static int doCal(StringBuilder sb){ScriptEngineManager sem = new ScriptEngineManager ();        ScriptEngine se = sem.getEngineByName ("js");        Double sum = 0.0;try {sum = (Double) se.eval (sb.toString());} catch (ScriptException e) {e.printStackTrace();}return sum.intValue();}}


0 0
原创粉丝点击