好久没来了,面试题一枚,征求答案

izard999 2016-05-05 01:31:58
前几天面试, 面试官让我现场做一道编程题(还不给我机器,让哥手写代码,带这么玩儿的吗?)
题目如下:
长度为100+的两个实数求和, 不可用BigDecimal, 只可用基础的API实现此程序。

话说当时这个程序我搞了大约30-40行伪代码, 那家伙说可以了。

今天有空实现了一下, 有效代码大约80行。

现来征求下广大大神的优质算法, 代码优秀的给高分, 谢谢
...全文
908 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2016-05-14
  • 打赏
  • 举报
回复
暴力加法,简单测试没啥问题。


public final class RealNumber {

	private final boolean positive;//正负
	private final char[] integer;//整数部分
	private final char[] decimal;//小数部分
	
	public RealNumber(String value) {
		positive = value.charAt(0)!='-';
		int index = value.indexOf('.');
		if(index>0){
			this.integer = value.substring(positive?0:1, index).toCharArray();
			this.decimal = value.substring(index+1).toCharArray();
		}else{
			this.integer = value.substring(positive?0:1).toCharArray();
			this.decimal = "".toCharArray();
		}
	}
	
	public RealNumber(boolean positive, char[] integer, char[] decimal) {
		super();
		this.positive = positive;
		this.integer = integer;
		this.decimal = decimal;
	}

	@Override
	public String toString() {
		StringBuilder buffer =  new StringBuilder(positive?"":"-");
		buffer.append(integer);
		if(decimal.length>0){
			buffer.append('.').append(decimal);
		}
		return buffer.toString();
	}
	
	public RealNumber add(RealNumber that){
		int size = Math.max(this.integer.length, that.integer.length)+Math.max(this.decimal.length,that.decimal.length);
		char[]thisnumber = new char[size+1];
		char[]thatnumber = new char[size+1];
		char[]result = new char[size+1];
		fill(thisnumber, '0');
		fill(thatnumber, '0');
		fill(result, '0');
		int index = Math.max(this.integer.length, that.integer.length);
		System.arraycopy(this.integer, 0, thisnumber, index-this.integer.length+1, this.integer.length);
		System.arraycopy(that.integer, 0, thatnumber, index-that.integer.length+1, that.integer.length);
		System.arraycopy(this.decimal, 0, thisnumber, index+1, this.decimal.length);
		System.arraycopy(that.decimal, 0, thatnumber, index+1, that.decimal.length);
		boolean positive = this.positive;
		if(this.positive==that.positive){
			boolean carry = false;
			int value = 0;
			for(int i=result.length-1; i>=0; i--){
				value = (thisnumber[i]-'0') + (thatnumber[i]-'0') + (carry?1:0);
				result[i] = (char)( value%10 + '0');
				carry = value>=10;
			}
		}else{
			int compare = compare(thisnumber,thatnumber);
			if(compare==0){
				return new RealNumber("0");
			}
			positive = compare>0 ? this.positive : that.positive;
			if(compare<0){
				char[] temp = thisnumber;
				thisnumber = thatnumber;
				thatnumber = temp;
			}
			boolean carry = false;
			int value = 0;
			for(int i = result.length-1; i>=0; i--){
				value = (thisnumber[i]-'0') - (thatnumber[i]-'0') - (carry?1:0);
				carry = value<0;
				value = value<0 ? 10+value : value;
				result[i] = (char)(value%10 + '0');
			}
		}
		int frontIndex = 0;
		for(frontIndex = 0; frontIndex < index; frontIndex++){
			if(result[frontIndex]!='0'){
				break;
			}
		}
		char integer[] = new char[index-frontIndex+1];
		System.arraycopy(result, frontIndex, integer, 0, integer.length);
		int lastIndex = result.length-1;
		for(lastIndex=result.length-1; lastIndex>=index; lastIndex--){
			if(result[lastIndex]!='0'){
				break;
			}
		}
		char decimal[] = new char[lastIndex-index];
		System.arraycopy(result, index+1, decimal, 0, decimal.length);
		return new RealNumber(positive, integer, decimal);
	}

	private static int compare(char[] thisnumber, char[] thatnumber) {
		for(int i=0; i<thisnumber.length; i++){
			if(thisnumber[i] == thatnumber[i]){
				continue;
			}
			return thisnumber[i] > thatnumber[i] ? 1 : -1;
		}
		return 0;
	}

	private static void fill(char[] buffer, char value) {
		for(int i=0;i<buffer.length;i++){
			buffer[i] = value;
		}
	}

	public static void main(String[] args) {
		RealNumber a = new RealNumber("100.1");
		RealNumber b = new RealNumber("-92.001");
		System.out.println(a.add(b).toString());
	}

}

piaopiao11 2016-05-11
  • 打赏
  • 举报
回复
试试这个,应该所有情况都是可以的。
public class B {
	
	
	public static void main(String[] args) throws Exception {
		Big a=new Big("99999999999999999999999999999999999999999999999999999");
		Big b=new Big("1");
		System.out.println(a+","+b);
		System.out.println(a.add(b));
	}
	
}

class Big{
	private String str;
	private List<Long> val;
	public Big(String str){
		this.str=str;
		val=new ArrayList<Long>();
		while(str.length()>18){
			String s=str.substring(str.length()-18);
			Long l=Long.parseLong(s);
			val.add(l);
			str=str.substring(0, str.length()-18);
		}
		val.add(Long.parseLong(str));
	}
	
    public Big add(Big b){
		for(int i=0;i<val.size()&&i<b.val.size();i++){
			val.set(i, val.get(i)+b.val.get(i));
		}
		if(b.val.size()>val.size()){
    		val.addAll(b.val.subList(val.size(),b.val.size()));
    	}
		int inc=0;
		String  sb=new String();
		DecimalFormat df=new DecimalFormat("000000000000000000");
		for(int i=0;i<val.size();i++){
			Long l=val.get(i);
			if(inc==1){
				l++;
			}
			inc=(l>999999999999999999l)?1:0;
			if(inc==1){
			   l=l-  1000000000000000000l;
			}
			val.set(i, l);
			if(i!=val.size()-1){
			sb=df.format(l)+sb;	
			}else{
			sb=l+sb;
			}
		}
		str=sb;
    	return this;
	}

        
    public String toString(){
    	List<Long> l=new ArrayList<Long>(val);
    	Collections.reverse(l);
    	return str+":"+l;
    }
}
奄灬苟且偷生 2016-05-11
  • 打赏
  • 举报
回复
引用 11 楼 bree06 的回复:
这个有很多问题.String a = "999968", b = "989";或者String a = "999968", b = "999968";
你很用心啊,我随手写的你居然测试了 那么久 膜拜了
x060508 2016-05-11
  • 打赏
  • 举报
回复
最后输出已string返回的么
tangxheng 2016-05-11
  • 打赏
  • 举报
回复
我也上个代码,原理就是按小学数学计算相加的方式
package dmiaes.client.view;



public class 大数据计算 {

	//大数据相加结果
	static String result = "";
	//用来存放临时进位的数
	static int jinwei = 0;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//加数和被加数
		String a = "123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123";
        String b = "7453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132";
        
        //计算
		compute(a, b);
		System.out.println(result);
	}

	/**
	 * 计算大数据相加
	 * @param str1 加数
	 * @param str2 被加数
	 */
	static void compute(String str1, String str2) {
		for (int i = Math.max(str1.length(), str2.length()); i > 0; i--) {
			//从大数据的最低位开始计算
			add(getlast(str1), getlast(str2) );
			
			//加数去除已计算过的最低位
			if(str1.length()>=1){
				str1 = str1.substring(0, str1.length()-1);
			}
			
			//被加数去除已计算过的最低位
			if(str2.length()>=1){
				str2 = str2.substring(0, str2.length()-1);
			}
		}
		
		//不能忘记计算结束后,最高的的进位需要加上来哦
		if(jinwei>0){
			result = jinwei + result;
			jinwei = 0;
		}
	}
	
	/**
	 * 取出字符串最后一个数字,即取得最低位
	 * @param str
	 * @return
	 */
	static int getlast(String str){
		if(str == null || "".equals(str)){
			return 0;
		}
		return Integer.valueOf(str.substring(str.length()-1)).intValue();
	}
	
	/**
	 * 取得进位,即两个1位int相加的10位数
	 * @param str
	 * @return
	 */
	static int getjinwei(String str){
		if(str == null || str == "" || str.length()<2){
			return 0;
		}
		return Integer.valueOf(str.substring(0, 1)).intValue();
	}

	/**
	 * 按小学数学计算方式,从最低位开始计算
	 * @param a 为加数当前最低位
	 * @param b 为被加数当前最低位
	 */
	static void add(int a, int b) {
		//当前计算到的最低位相加,同时加上上次最低位相加的进位
		int temp = a + b + jinwei;
		String strTemp = String.valueOf(temp);
		
		//将结果拼到当前结果的最前面
		result = getlast(strTemp) + result;
		
		//得到下次计算的进位
		jinwei = getjinwei(strTemp);
	}

}
bajinggong 2016-05-11
  • 打赏
  • 举报
回复
长度为100+的两个实数求和 实数包括有理数和无理数,也就是说既有正数也有负数,既有整数部分也可能有小数部分。 写了一下都快200行了
jsf06 2016-05-10
  • 打赏
  • 举报
回复

public class CalculatorMain  {
	public static void main(String[] args) {
		BigDicimalCalculator calculator = new BigDicimalCalculator();
		System.out.println(calculator.add("99999999","999999999"));
	}
}

class BigDicimalCalculator {
	public String add(final String a, final String b) {
		if (a==null || a.equals("")) {
			return b;
		}
		if (b==null || b.equals("")) {
			return a;
		}
		StringBuilder c = new StringBuilder();
		int i=a.length() - 1;
		int j=b.length() - 1;
		boolean hasOverBit = false;
		while (i >= 0 && j >= 0) {
			int ia = Integer.parseInt(a.substring(i, i+1));
			int ib = Integer.parseInt(b.substring(j, j+1));
			int ic = ia + ib;
			if (hasOverBit) {
				ic++;
				hasOverBit = false;
			}
			if (ic > 9) {
				hasOverBit = true;
				ic = ic % 10;
			}
			c.insert(0, ic);
			i--;
			j--;
		}
		while (i>=0) {
			int ia = Integer.parseInt(a.substring(i, i+1));
			int ic = ia;
			if (hasOverBit) {
				ic++;
				hasOverBit = false;
			}
			if (ic > 9) {
				hasOverBit = true;
				ic = ic % 10;
			}
			c.insert(0, ic);
			i--;
		}
		while (j>=0) {
			int ib=Integer.parseInt(b.substring(j, j+1));
			int ic = ib;
			if (hasOverBit) {
				ic++;
				hasOverBit = false;
			}
			if (ic > 9) {
				hasOverBit = true;
				ic = ic % 10;
			}
			c.insert(0, ic);
			j--;
		}
		if (hasOverBit) {
			c.insert(0, 1);
		}
		return c.toString();
	}
}
bree06 2016-05-10
  • 打赏
  • 举报
回复
发一个不转int的.两个数字最多是做10以内的加法最大18用不着转成int计算.
public static void main(String[] args) {
    String a = "999968", b = "989";
    byte[] l, s;
    final char zero = '0', nine = '9';
    if (a.length() > b.length()) {
        l = a.getBytes();
        s = b.getBytes();
    } else {
        l = b.getBytes();
        s = a.getBytes();
    }
    if ((l.length == s.length && l[0] + s[0] >= nine) || l[0] >= nine) {
        byte[] _l = new byte[l.length + 1];
        System.arraycopy(l, 0, _l, 1, l.length);
        l = _l;
        l[0] = zero;
    }
    int il = l.length, is = s.length, i, start;
    for (i = 1; i <= is; i++) {
        byte p = (byte) (l[il - i] + s[is - i] - zero);
        if (p > nine) {
            l[il - i] = (byte) (p - 10);
            l[il - i - 1] += 1;
        } else {
            l[il - i] = p;
        }
    }
    do {
        if (l[il - i] > nine) {
            l[il - i] -= 10;
            l[il - i - 1] += 1;
        } else break;
    } while (i++ < il);
    System.out.println(new String(l, start=l[0]==zero?1:0, il-start));
}
bree06 2016-05-10
  • 打赏
  • 举报
回复
引用 1 楼 ch1240249252 的回复:
我写了一个最基础的,因为难的我不会 有效代码20多行
package socket;


public class meth {

	public static void main(String[] args) {
		String a = "123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123";
		String b = "7453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132";
		String c ="";
		int ab;
		boolean f=false;
		if (a.length()>b.length()) {
			ab=a.length()-b.length();
			for (int i = a.length(); i >0; i--) {
				String aa = a.substring(i-1,i);
				String bb="";
				if(i-1-ab>=0){
					bb = b.substring(i-1-ab<0?0:i-1-ab,i-ab<0?0:i-ab);
				}else{
					bb="0";
				}
				if(f){
					c=((Integer.parseInt(aa)+Integer.parseInt(bb))%10+1)+c;
				}else{
					c=((Integer.parseInt(aa)+Integer.parseInt(bb))%10)+c;
				}
				if(Integer.parseInt(aa)+Integer.parseInt(bb)>10){
					f=true;
				}else{
					f=false;
				}
			}
		}
		System.out.println(c);
		
	}

}
这个有很多问题.String a = "999968", b = "989";或者String a = "999968", b = "999968";
lingyun12580 2016-05-10
  • 打赏
  • 举报
回复
连题目都没看懂
ouzhijian 2016-05-10
  • 打赏
  • 举报
回复
引用 楼主 izard999 的回复:
前几天面试, 面试官让我现场做一道编程题(还不给我机器,让哥手写代码,带这么玩儿的吗?) 题目如下: 长度为100+的两个实数求和, 不可用BigDecimal, 只可用基础的API实现此程序。 话说当时这个程序我搞了大约30-40行伪代码, 那家伙说可以了。 今天有空实现了一下, 有效代码大约80行。 现来征求下广大大神的优质算法, 代码优秀的给高分, 谢谢
200000000000000000000000000000000000 200000000000000000000000000000000000 没值
ouzhijian 2016-05-10
  • 打赏
  • 举报
回复
最好把 int改成long
ouzhijian 2016-05-10
  • 打赏
  • 举报
回复
@Test // public void addTest(String str1,String str2) { public void addTest() { String a="2000000000000000000001230000000321300000000001231200000000000000123000000000000000001230000000000000012300000000"; String b="21000000000130000000000000001230000000000000000000000012321300000000000000000000000123000000000000000000"; BigDecimal bigDecimal=new BigDecimal(a); BigDecimal bigDecimal1=new BigDecimal(b); System.out.println(bigDecimal.add(bigDecimal1)); System.out.println(bigDecimal.add(bigDecimal1).toString().length()); //a字符串一定要长于b或等于 // if(str1.length()>str2.length()){ // a=str1; // b=str2; // }else{ // a=str2; // b=str1; // } int bl= b.length(); ArrayList item=new ArrayList(); int d=0; for (int i=b.length(); i>0;i--) { int bb= Integer.parseInt(b.substring(i-1,i)); int c=Integer.parseInt(a.substring(a.length()-b.length()+i-1,a.length()-b.length()+i))+ bb; if(i!=b.length()&&d!=0){ c=c+d; } if(c>=10){ d=1; }else{ d=0; } if(c>=10){ item.add(c-10); }else{ item.add(c); } } if(d!=0){ item.add(1); } Collections.reverse(item); int max=0; if(a.length()==b.length()){ String rai=item.toString().replaceAll("[\\[\\]\\,\\s]",""); System.out.println(rai); System.out.println(rai.length()); }else{ if(a.length()==item.size()){ max=Integer.parseInt(a.substring(0,1))+(Integer)item.get(0); }else{ max=Integer.parseInt(a.substring(0,a.length()-item.size()+1)); max= max+(Integer)item.get(0); } String rai=item.toString().replaceAll("[\\[\\]\\,\\s]",""); rai= max+""+rai.substring(1,rai.length()); System.out.println(rai); System.out.println(rai.length()); } }
月凉西厢 2016-05-05
  • 打赏
  • 举报
回复
上个简陋的代码,狠心逻辑很简单,类似单片机的加法器
public class Test {
 
	public class BigInt{
		int low;
		int mid;
		int high;
		
		public BigInt(int high,int mid,int low) {
			this.high=high;
			this.mid=mid;
			this.low=low;
		}
		
		public BigInt() {
			
		}
		
		public BigInt add(BigInt b) {
			
			if(this.low>=1000000000||b.low>=1000000000||
				this.mid>=1000000000||b.low>=1000000000||
				this.high>=1000000000||b.low>=1000000000){
				return null;
			}
			BigInt result=new BigInt();
			result.low=this.low+b.low;
			int low2mid=result.low/1000000000;
			result.low=result.low%1000000000;
			
			result.mid=this.mid+b.mid+low2mid;
			int mid2high=result.mid/1000000000;
			result.mid=result.mid%1000000000;
			
			result.high=this.high+b.high+mid2high;
			int isOver=result.high/1000000000;
			result.high=result.high%1000000000;
			if(isOver>0){return null;}
			
			
			return result;
		}
		
		public String toString() {
			String str=new String(String.format("%9d", high)+String.format("%9d", mid).replace(" ", "0")+String.format("%9d", low).replace(" ", "0"));
			return str;
		}
	}
	
    public static void main(String[] args) {
    	Test test=new Test();
    	test.addTest();
    }
    
    public void addTest() {
		BigInt aBigInt=new BigInt(123456789,6789,123456789);
		BigInt bBigInt=new BigInt(234567890,7890,234567890);
		
		BigInt result=aBigInt.add(bBigInt);
		
		System.out.println(result);
	}
}
奄灬苟且偷生 2016-05-05
  • 打赏
  • 举报
回复
引用 3 楼 izard999 的回复:
大致差不多是这个意思吧, 没处理小数而已 - -!
差不多就行了,大神,说好的面试
izard999 2016-05-05
  • 打赏
  • 举报
回复
大致差不多是这个意思吧, 没处理小数而已 - -!
奄灬苟且偷生 2016-05-05
  • 打赏
  • 举报
回复
等我再优化优化,我12行有点问题加一个,加一个三目就可以了 我就不手动再改了
奄灬苟且偷生 2016-05-05
  • 打赏
  • 举报
回复
我写了一个最基础的,因为难的我不会 有效代码20多行
package socket;


public class meth {

	public static void main(String[] args) {
		String a = "123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123";
		String b = "7453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132745365233421327453652334213274536523342132";
		String c ="";
		int ab;
		boolean f=false;
		if (a.length()>b.length()) {
			ab=a.length()-b.length();
			for (int i = a.length(); i >0; i--) {
				String aa = a.substring(i-1,i);
				String bb="";
				if(i-1-ab>=0){
					bb = b.substring(i-1-ab<0?0:i-1-ab,i-ab<0?0:i-ab);
				}else{
					bb="0";
				}
				if(f){
					c=((Integer.parseInt(aa)+Integer.parseInt(bb))%10+1)+c;
				}else{
					c=((Integer.parseInt(aa)+Integer.parseInt(bb))%10)+c;
				}
				if(Integer.parseInt(aa)+Integer.parseInt(bb)>10){
					f=true;
				}else{
					f=false;
				}
			}
		}
		System.out.println(c);
		
	}

}

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧