大数相减

题目描述:

 输入:两个正的大数

输出:两个大数的差

代码实现:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @author njupt
 * 两个正大数相减
 */
public class BigNumSub {

	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		String minuend;//被减数
		String meiosis;//减数
		String difference;//差值
		while(cin.hasNext()){
			minuend=cin.next();
			meiosis=cin.next();
			if(!valid(minuend)||!valid(meiosis))//合法性验证
				return;
			difference=bigNumSub(minuend,meiosis);
			System.out.println(difference);
		}
	}

	
	/**
	 * @param minuend 被减数
	 * @param meiosis 减数
	 * @return difference 差值
	 * 
	 * 1.判断被减数和减数的大小
	 * (1):被减数minuend的位数大于meiosis减数的位数,则直接相减
	 * (2):被减数minuend的位数小于meiosis减数的位数,交换相减,结果加上-(负号)
	 * (3):被减数minuend的位数等于meiosis减数的位数,判断两者的大小:
	 *     a:minuend>=meiosis,则直接相减
	 *     b:minuend<meiosis,交换相减,结果加上-(负号)
	 */
	private static String bigNumSub(String minuend, String meiosis) {
	
		int minLen=minuend.length();//被减数的长度
		int meiLen=meiosis.length();//减数的长度
		boolean addSign=false;//是否交换被减数和减数
		String difference;//结果
        if(minLen<meiLen){
			addSign=true;
			String temp=minuend;
			minuend=meiosis;
			meiosis=temp;
		}else if(minLen==meiLen){//两个位数相等
			//判断大小
			int re=judge(minuend,meiosis);
			if(re==-1)//小于,要交换
			{
				addSign=true;
				String temp=minuend;
				minuend=meiosis;
				meiosis=temp;
			}else if(re==0){
				return "0";
			}
		}
		//相减
		difference=sub(minuend,meiosis);
		if(addSign)
			return "-"+difference;
		
		return difference;
	}

	/**
	 * @param minuend
	 * @param meiosis
	 * @return difference
	 * 两个大数相减,这里按照数学上的大小已经是被减数minuend>=meiosis
	 */
	private static String sub(String minuend, String meiosis) {
		int minLen=minuend.length();//被减数的长度
		int meiLen=meiosis.length();//减数的长度
		int dif=minLen-meiLen;//两个数的相差几位
		boolean borrow=false;//借位
		List<Integer> list=new ArrayList<Integer>();//放置每位相减的结果
		int i=meiLen-1;
		int j=i+dif;
		int min=0;
		int mei=0;
		for (; i >=0; j--,i--) {
			min=Integer.valueOf(minuend.charAt(j))-48;
			mei=Integer.valueOf(meiosis.charAt(i))-48;
			int result=0;
			
			if(borrow){//有借位情况
				min=min-1;
			}
			if(min>=mei){
				result=min-mei;
			}else{//需要借位
				result=min+10-mei;
				borrow=true;
			}
			list.add(result);
		}
		//将剩余的的被减数的位记录下来
		for (; j>=0; j--) {
			min=Integer.valueOf(minuend.charAt(j))-48;
			if(borrow){//上一次有借位
				min=min-1;
				borrow=false;
			}
			list.add(min);
		}
		StringBuilder sb=new StringBuilder();
		//这里注意把去掉前面的零位
		boolean remove=true;
		for (int k=list.size()-1;k>=0;k--) {
			int re=list.get(k);
			if(re!=0||remove==false){
				sb.append(re);
				remove=false;
			}
		}
		return sb.toString();
	}


	/**
	 * @param minuend
	 * @param meiosis
	 * @return result
	 * 判断两个等位数大数在数学意义上的大小关系
	 */
	private static int judge(String minuend, String meiosis) {
		int result=0;//默认被减数大于减数
		int len=minuend.length();
		int i=0;
		for(;i<len;i++){
			if(minuend.charAt(i)>meiosis.charAt(i)){//大于
				result=1;
				return result;
			}else if(minuend.charAt(i)<meiosis.charAt(i)){//小于
				result=-1;
				return result;
			}
		}
		return result;
	}


	//输入合法性验证
	private static boolean valid(String number) {
		if(null==number&&"".equals(number))
			return false;
		char[] charArr=number.toCharArray();
		if(charArr[0]=='0')//首字符不能为0
			return false;
		for (int i = 1; i < charArr.length; i++) {//每个字符介于0到9
			char temp=charArr[i];
			if(temp<'0'||temp>'9')
				return false;
		}
		return true;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值