两数之和的衍生题:两个超长的正整数数字字符串,求两数之和?

一)两数之和

题意:给定两个超长的数字字符串,在两个数都是正整数的情况下,计算两个数之和。

备注:该章主要是为了提供一种计算思路,就暂不考虑有负整数和小数的情况。

分析:由于数字超长,肯定不能转换成int和long这些类型来计算,会存在溢出的情况。

思路:由于计算的顺序是从右往左计算,满10进1的规则,所以可以考虑把字符串先进行反转,然后一位一位进行加法,这样相当于只需要考虑20内的加法,应该两个数字相加不可能超过20。

步骤:

一、先用正则表达式校验两个字符串是否只包含数字

二、把两个字符串转换成char[]数组,并进行反转,这是为了方便一位一位计算。

三、计算出两个字符串各自的长度、在进行求和的时候,用较长字符串的长度作为循环条件。

四、然后在循环中一位一位数进行求和,每一位计算的时候,都需要判断满10进1的情况,如果较短的字符串数字已经计算完,只需要考虑最后一位是否满10进1了,再直接单独计算较长字符串数字的和。

五、需考虑两个数字字符串一样长、又满10进1的情况,这种情况需要在前面多累加一个1。

二)功能源码

/**
 * 两个超长的正整数数字字符串,求两数之和?
 * @param  String str1 =     "123456789987654321123456789";
 * @param  String str2 =    "9876543211234567899876543219";
 * @return String result = "10000000001222222221000000008";
 */
public static String numberStringSum(String str1, String str2) {
	if (str1 == null || str2 == null) {
		return null;
	}
		
	// 校验字符串是否就包含数字和'-'
	String regex = "\\d+"; // 只考虑正整数
	if (!str1.matches(regex) || !str2.matches(regex)) {
		return null;
	}
		
	char[] charStr1 = str1.toCharArray();
	char[] charStr2 = str2.toCharArray();
		
	// 把两个字符串进行反转,然后两两相加
	char[] ch1 = reverse(charStr1);
	char[] ch2 = reverse(charStr2);
		
	// 判断两个字符串的长度
	int maxLen = ch1.length >= ch2.length ? ch1.length: ch2.length;
	int minLen = ch1.length <= ch2.length ? ch1.length: ch2.length;
		
	// 判断两个字符串哪一个长
	boolean isLen = ch1.length >= ch2.length ? true: false;
		
	int sum = 0; // 默认0
	int inValue = 0; // 默认的进位值
	StringBuilder builder = new StringBuilder();
		
	for (int i = 0; i < maxLen; i++) {
		// 小于最小长度的字符串时,两个数相加
		if (i < minLen) {
			int num1 = Integer.parseInt(String.valueOf(ch1[i]));
			int num2 = Integer.parseInt(String.valueOf(ch2[i]));
				
			// 两个数相加
			sum = num1 + num2 + inValue;
		} else {
			// 小长度字符串相加完, 计算大长度字符串, 考虑进位值
			int num = 0;
			if (isLen) {
				num = Integer.parseInt(String.valueOf(ch1[i]));
			} else {
				num = Integer.parseInt(String.valueOf(ch2[i]));
			}
			sum = num + inValue;
		}
		inValue = sum/10; // 判断是否有进位值
			
		// 把值存储起来
		builder.append(sum%10);
	}
	// 两个字符串长度一样,但又有进位值的情况
	builder.append(inValue == 1 ? inValue : "");
		
	// 返回的字符串
	return builder.reverse().toString();
}
	
/**
 * 字符串反转
 * @param str
 * @return
 */
public static char[] reverse(char[] chars) {
	char[] result = new char[chars.length];
	int index = 0;
	// 反转
	for (int i = chars.length - 1; i >= 0; i--) {
	   	result[index++] = chars[i];
	}
	return result;
}

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值