android/移动端面试#1 大数相加
来源:互联网 发布:linux如何开启ftp服务 编辑:程序博客网 时间:2024/06/10 01:11
最近在找工作,有一些面试,有一些面试题,做点整理和回顾吧。
题目是:
有两个大数(Int32放不下的),要求他们的和
一接手我就考虑用字符串的模拟加法来做,然后就和面试官说了,可能当时时间有点赶,面试官没要求我写代码出来。
今天自己计时写了一下,这里给下代码:
public String computer(String one,String another) throws IllegalArgumentException{if(one == null || another == null || one.isEmpty() || another.isEmpty()){throw new IllegalArgumentException("input is empty");}int olength = one.length();int alength = another.length();int minlength = Math.min(olength, alength);int length = Math.max(olength,alength) + 1;byte[] out = new byte[length];char zero = '0';int o,a;int current = 0 ;boolean flag = false;int k = length - 1;for(int i = olength - 1,j = alength - 1; i >= 0 && j >= 0 ; i--,j--){o = one.charAt(i) - zero;a = another.charAt(j) - zero;if(o < 0 || o > 9 || a < 0 || a > 9){throw new IllegalArgumentException("input not a num(0~9),check your input");}current = o + a ;if(flag) {current ++;}if(current > 9){flag = true;current -= 10; }else{flag = false;}out[k] = (byte)(zero + current);k--;}if(olength > minlength){flag = addLast(zero,one,flag,k,out);}else if(alength > minlength){flag = addLast(zero,another,flag,k,out);}out[0] = '1';if(flag){return new String(out);}else{return new String(out).substring(1);}}private boolean addLast(char zero,String s,boolean flag,int k,byte[] out)throws IllegalArgumentException{int t;int current;for(int i = k - 1 ; i >= 0 ; i-- ){t = s.charAt(i) -zero;if(t < 0 || t > 9){throw new IllegalArgumentException("input not a num(0~9),check your input");}current = t;if(flag){current++;}if(current > 9){flag = true;current -= 10; }else{flag = false;}out[k] = (byte)(zero + current);k--;}return flag;}
简单测试用例:
System.out.println("-----test1------");try{String a = "789";String b ="90009999999";String c = computer(a, b);System.out.println(a);System.out.println(b);System.out.println(c);}catch(IllegalArgumentException e){e.printStackTrace();}System.out.println("-----test2------");try{String a = "1116666666666666666666611111188789";String b = "1";String c = computer(a, b);System.out.println(a);System.out.println(b);System.out.println(c);}catch(IllegalArgumentException e){e.printStackTrace();}System.out.println("-----test3------");try{String a = "123456789";String b ="809999999";String c = computer(a, b);System.out.println(a);System.out.println(b);System.out.println(c);}catch(IllegalArgumentException e){e.printStackTrace();}System.out.println("-----test4------");try{String a = "999";String b ="111";String c = computer(a, b);System.out.println(a);System.out.println(b);System.out.println(c);}catch(IllegalArgumentException e){e.printStackTrace();}System.out.println("-----test5------");try{String a = "1234num56789";String b ="809999999";String c = computer(a, b);System.out.println(a);System.out.println(b);System.out.println(c);}catch(IllegalArgumentException e){e.printStackTrace();}
回头看网上的代码,找到一个代码行数大概在35行的,他对string做了反转,再用了一个int[]的数字去存结果,最后才转化过去。
然后我就发现可以直接用一行代码实现:
new BigInteger(one).add(new BigInteger(another)).toString();
(实践中确实很少遇见这种要求,所以,真不知道有这个库函数-_-)
顺便看看一下openjdk中是怎么写的吧:
看了下代码行数,有三千多行,我只挑重点的看吧。
1、先把字符串按照正负、进制(2~36)存在一个符号位和数据位int[]中
2、如果符号位相同(加法)分段求和
/** * Adds the contents of the int arrays x and y. This method allocates * a new int array to hold the answer and returns a reference to that * array. */ private static int[] add(int[] x, int[] y) { // If x is shorter, swap the two arrays if (x.length < y.length) { int[] tmp = x; x = y; y = tmp; } int xIndex = x.length; int yIndex = y.length; int result[] = new int[xIndex]; long sum = 0; // Add common parts of both numbers while(yIndex > 0) { sum = (x[--xIndex] & LONG_MASK) + (y[--yIndex] & LONG_MASK) + (sum >>> 32); result[xIndex] = (int)sum; } // Copy remainder of longer number while carry propagation is required boolean carry = (sum >>> 32 != 0); while (xIndex > 0 && carry) carry = ((result[--xIndex] = x[xIndex] + 1) == 0); // Copy remainder of longer number while (xIndex > 0) result[--xIndex] = x[xIndex]; // Grow result if necessary if (carry) { int bigger[] = new int[result.length + 1]; System.arraycopy(result, 0, bigger, 1, result.length); bigger[0] = 0x01; return bigger; } return result; }
3、如果是减法
/** * Subtracts the contents of the second int arrays (little) from the * first (big). The first int array (big) must represent a larger number * than the second. This method allocates the space necessary to hold the * answer. */ private static int[] subtract(int[] big, int[] little) { int bigIndex = big.length; int result[] = new int[bigIndex]; int littleIndex = little.length; long difference = 0; // Subtract common parts of both numbers while(littleIndex > 0) { difference = (big[--bigIndex] & LONG_MASK) - (little[--littleIndex] & LONG_MASK) + (difference >> 32); result[bigIndex] = (int)difference; } // Subtract remainder of longer number while borrow propagates boolean borrow = (difference >> 32 != 0); while (bigIndex > 0 && borrow) borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1); // Copy remainder of longer number while (bigIndex > 0) result[--bigIndex] = big[bigIndex]; return result; }
4、输出就默认转成十进制
小结一下:
我花的时间大概在一个小时,代码行数在70行上下,没反转,尽量不存数据,中间处理过程细节多了一点,面试的时候可能要注意的是:
0、漏了一种边界情况,输入的大数是负数
1、想清楚再动手写代码
2、不要太扣细节,保存简单 快速
最近找了一些leetcode的题在看,发现有些题目是需要思考比较久的,还是要刷算法题,至少知道解决的可能性思路。
上周面试官还问了一个内存泄漏的问题,当时没get到他要问的是什么,我就回答了一下我所经历过的内存泄漏。刚才突然想到,他问的问题可能是,有哪些情况会导致在Activity中导致内存泄漏。
1、如果在生命周期比较长的,例如service中保持activity的引用
2、或者是在static中保持activity的引用
3、或者是在内部类、线程中保存activity的引用
都有可能导致activity的内存泄漏
0 0
- android/移动端面试#1 大数相加
- android/移动端面试#2
- 大数相加 + 方法1
- 大数相加方法------1
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 大数相加
- 实验_DataSaveSdcard
- 1生产者 10消费者 3缓冲区
- Mac 开发环境变量设置教程
- JavaEE中分页的具体实现
- 第14周练习-1 数组大折腾(4)
- android/移动端面试#1 大数相加
- C++中 Vector的用法详解
- u-boot-2016.11移植u-boot.bin
- 工程师的五个等级
- El标签和JSTL总结
- JavaScript OOP
- STM32学习笔记6(TIM模块定时器)
- Android实现ios点击状态栏回到顶部效果(直接转的网址)
- springMVC笔记系列(19)——控制器实现详解(上)