标签:lan oct cti ring span clu 正整数 var meta
两个超大数的相加,主要是判断进一的情况,另外int型有边界限制,所以转换成字符串型进行处理。
<?php
/**
* @description 两个超大的数字相加
* @param $numA string 第一个大数
* @param $numB string 第二个大数
* @return string 两个大数之和
**/
function largeNumberAdding(string $numA, string $numB) {
//边界校验
if (empty($numA)) {
if (empty($numB)) {
return ‘0‘;
} else {
return $numB;
}
} else {
if (empty($numB)) {
return $numA;
}
}
$result = $tmpRes = $head = $tmpHead = ‘‘;
$lenA = strlen($numA);
$lenB = strlen($numB);
$revA = strrev($numA);
$revB = strrev($numB);
$common = min($lenA, $lenB);
//截取超出部分长度
$tmpHead = ($lenA > $lenB) ? substr($revA, $common) : substr($revB, $common);
//是否进一
$addOne = false;
//重叠部分处理
for ($i=0; $i<$common; $i++) {
$tmp = (int)$revA[$i] + (int)$revB[$i];
$addOne && $tmp += 1;
$tmpRes .= (string)($tmp % 10);
$addOne = ($tmp >= 10) ? true : false;
}
//头部处理
if ($addOne) {
if ($tmpHead) {
$headlen = strlen($tmpHead);
for ($j=0; $j<$headlen; $j++) {
$tmp = (int)$tmpHead[$j];
if ($addOne) {
$tmp += 1;
$tmpRes .= (string)($tmp % 10);
$addOne = ($tmp >= 10) ? true : false;
} else {
$tmpRes .= (string)$tmp;
}
}
}
//相同位数进一直接+1
$addOne && $tmpRes .= ‘1‘;
} else {
$tmpRes .= $tmpHead;
}
//将结果倒转
$result = strrev($tmpRes);
return $result;
}
$a = ‘988881111111110000000000000000000‘;
$b = ‘10002222222222‘;
$res = largeNumberAdding($a, $b);
var_dump($res);
输出结果:
string(33) "988881111111110000010002222222222"
时间复杂度: O(n)
思考:
1, 这里的超大数默认为正整数,没有支持负数或浮点数,需要优化;
标签:lan oct cti ring span clu 正整数 var meta
原文地址:https://www.cnblogs.com/1994july/p/12483462.html