首页 > 试题广场 > 大数加法
[编程题]大数加法
  • 热度指数:24471 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
(字符串长度不大于100000,保证字符串仅由'0'~'9'这10种字符组成)
示例1

输入

"1","99"

输出

"100"

说明

1+99=100 
非本人所想,从网上看到的实现方法,感觉十分优雅,就分享一下
 function solve(a,b){
    var res='', c=0;
    a = a.split('');
    b = b.split('');
    while (a.length || b.length || c){
        c += ~~a.pop() + ~~b.pop();
        res = c % 10 + res;
        c = c>9;
    }
    return res.replace(/^0+/,'0');
}
说一下思路
1. 通过 split 将 a 和 b 转为数组;

2. while 循环进行判断,如果 a 数组或 b 数组不为空,或 c 值存在,则继续循环;

3. 通过 pop 方法去除数组的最后一项,并拿到最后一项的返回值,进行相加,传给 c 。
但此处要注意的一点是:因为 a 和 b 的长度不相同,所以 a 或 b 的数组元素可能为 undefined ,而数字加 undefined 的值为 NaN ,为了避免此情况,可以使用 ~~undefined 将 undefined 转换为 0 ;

4. 对 c 取余,拼接到 res 字符串的前面;

5. 之后对 c 进行判断,如果 c 大于 9 ,则 c 为 true, 进入下一轮循环。( c 在进行下一轮相加时,会从 true 转换为 1,因此就达到了进一的效果 ) 

总结:
拿出 a 数组和 b 数组的最后一项并与 c 相加赋给 c , 再对 c 取余拼接到 res 前面。
对 c 进行判断并赋予布尔值,之后循环
发表于 2020-11-26 21:13:59 回复(0)
按照题意,用比较老实的做法(自己造轮子)。
(1)通过前补0的方式,先对齐两个字符串数字的长度,并且在这个长度上加上一位,作为备用进位。
之后,两两对应位置,进行相加,判断和是否大于10:
(2)大于10则前一位进位加1,本位留个位数字。
(3)小于10则直接相加,留下。
(4)最终检查一下首位是否为0(为0,代表无进位,删除首位字符即可)
最后,返回答案字符串
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        
        int max_length = s.length() > t.length() ? s.length() + 1 : t.length() + 1;        
        string temp_zero1(max_length - s.length(), '0');
        s = temp_zero1 + s;   //对s补0操作
        string temp_zero2(max_length - t.length(), '0');
        t = temp_zero2 + t;    //对t补0操作

        string ans;
        char temp_num[2];
        temp_num[1] = '\0';
        for (int i = s.length() - 1; i >= 0; i--) //从最末一位开始往前加
        {
            if ((s[i] - '0') + (t[i] - '0') >= 10) //有进位
            {
                s[i - 1] = s[i - 1] + 1; // 进一位
                temp_num[0] = '0' + ((s[i] - '0') + (t[i] - '0') - 10);
                ans.insert(0, temp_num);
            }
            else //无进位
            {
                temp_num[0] = '0' + (s[i] - '0') + (t[i] - '0');
                ans.insert(0, temp_num);
            }
        }

        if (ans[0] == '0')
            ans = ans.erase(0, 1);
        return ans;
    }
};


编辑于 2020-12-16 15:09:39 回复(2)
//好方法
import java.util.*;
import java.math.BigInteger;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public String solve (String s, String t) {
        // write code here
       if(s==null||"".equals(s)){
           return t;
       }
       if(t==null||"".equals(t)){
           return s;
       }
       int i=s.length()-1;
       int j=t.length()-1;
       int m1=0,m2=0,carray=0;//进位
       StringBuilder sb = new StringBuilder();
       while(i>=0||j>=0){
           if(i>=0){
               m1=s.charAt(i)-'0';
           }else{
               m1=0;
           }
           if(j>=0){
                m2=t.charAt(j)-'0';
           }else{
                m2=0;
           }
           int sum=m1+m2+carray;
           carray=sum/10;
           sb.append((char)((sum%10)+'0'));
           i--;
           j--;
       }
       if(carray!=0) sb.append('1');
       sb.reverse();
       return sb.toString();
    }
}

发表于 2021-01-22 21:12:33 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        // write code here
        int i=s.size()-1;int j=t.size()-1;   //双指针法
        int cur=0;  //进位
        string ans;
        while(i>=0||j>=0||cur)
        {
            if(i>=0)  cur+=s[i--]-'0';
            if(j>=0)  cur+=t[j--]-'0';
            ans=to_string(cur%10)+ans;
            cur/=10;
        }
        return ans;
    }
};

发表于 2021-01-13 22:04:34 回复(1)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        // write code here
        reverse(s.begin(), s.end());
        reverse(t.begin(), t.end());
        string res;
        int k = 0;
        for(int i = 0; i < s.size() || i < t.size(); i++){
            if(i < s.size()) k += s[i] - '0';
            if(i < t.size()) k += t[i] - '0';
            res += k % 10 + '0';
            k /= 10;
        }
        if(k)res += '1';
        reverse(res.begin(), res.end());
        return res;
    }
};

发表于 2020-12-15 21:23:27 回复(0)
要用魔法打败魔法
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
# 计算两个数之和
# @param s string字符串 表示第一个整数
# @param t string字符串 表示第二个整数
# @return string字符串
#
class Solution:
    def solve(self , s , t ):
        # write code here
        return eval(s+'+'+t)
补充一下:寻找长度最长字符串;列表化,翻转,一个一个数字相加,carry是进位,最后结果翻转。
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
# 计算两个数之和
# @param s string字符串 表示第一个整数
# @param t string字符串 表示第二个整数
# @return string字符串
#
class Solution:
    def solve(self , s , t ):
        # write code here
        res = ''
        if not s and not t: return res
        if len(s) < len(t):
            s,t = t,s
        s,t = list(s),list(t)
        s[:],t[:] = s[::-1],t[::-1]
        carry = 0  
        for i in range(len(s)):
            a = int(s[i])
            b = 0
            if i < len(t):
                b = int(t[i])
            res = res + str((a+b+carry)%10)
            carry = (a+b+carry)//10
        if carry != 0: res = res + str(carry)
        return res[::-1]


编辑于 2020-12-25 17:36:13 回复(3)
  • 算法
    • 1.保证s是较长的字符串,t是较短的字符串;如果不是,交换之
    • 2.用StrngBuilder保存计算结果,remainder保留进位;逐位计算和,计算到t字符串结束,每次计算和记得加上进位
    • 3.计算s比t多出的字符,同样记得加上进位
    • 4.最后如果进位不为0,结果还要加上进位
    • 5.得到的字符串翻转即是答案
public String solve (String s, String t) {
    if (s.length() < t.length()) {
        String temp = s;
        s = t;
        t = temp;
    }

    StringBuilder sb = new StringBuilder();
    int longLength = s.length();
    int shortLength = t.length();
    int carry = 0;
    for (int i = 0; i < shortLength; i++) {
        int add = (s.charAt(longLength-1-i) - '0') + (t.charAt(shortLength-1-i) - '0') + carry;
        sb.append(add % 10);
        carry = add / 10;
    }
    for (int i = shortLength; i < longLength; i++) {
        int add = (s.charAt(longLength-1-i) - '0') + carry;
        sb.append(add % 10);
        carry = add / 10;
    }
    if (carry != 0) {
        sb.append(carry);
    }
    return sb.reverse().toString();
}
编辑于 2020-10-03 23:44:01 回复(0)
能想到的最简洁的代码
public String solve (String s, String t) {
    StringBuilder ans = new StringBuilder();
    int tmp = 0;
    int ls = s.length() -1, lt = t.length()-1;
    while (ls >= 0 || lt >= 0 || tmp == 1) {
        int l = ls >= 0 ? (s.charAt(ls--) - '0') : 0;
        int r = lt >= 0 ? (t.charAt(lt--) - '0') : 0;
        int plus = l + r + tmp;
        tmp = plus / 10;
        char a = (char)(plus % 10 + '0');
        ans.append(a);
    }
    return ans.reverse().toString();
}
发表于 2020-10-18 11:26:16 回复(2)
import java.util.*;
import java.math.BigInteger;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public String solve (String s, String t) {
        //Java 大数操作BigInteger 可以直接返回结果
        BigInteger bi1 = new BigInteger(s);
        BigInteger bi2 = new BigInteger(t);
        return bi1.add(bi2).toString();
    }
}

发表于 2021-03-04 21:18:17 回复(0)
感觉我写的好复杂...   

  public String solve(String s, String t) {
        // write code here
        boolean flag = false;
        int lenS = s.length() - 1;
        int lenT = t.length() - 1;
        StringBuilder result = new StringBuilder();
        while (lenS >= 0 && lenT >= 0) {
            int r = (s.charAt(lenS) - 48) + (t.charAt(lenT) - 48);
            if (flag) {
                r += 1;
                flag = false;
            }
            if (r >= 10) {
                flag = true;
                r = r - 10;
            }
            result.insert(0, r);
            lenS--;
            lenT--;
        }
        if (lenS >= 0) {
            for (int i = lenS; i >= 0; i--) {
                int r = s.charAt(i) - 48;
                if (flag) {
                    r += 1;
                    flag = false;
                }
                if (r >= 10) {
                    flag = true;
                    r -= 10;
                }
                result.insert(0, r);
            }
        }
        if (lenT >= 0) {
            for (int i = lenT; i >= 0; i--) {
                int r = t.charAt(i) - 48;
                if (flag) {
                    r += 1;
                    flag = false;
                }
                if (r >= 10) {
                    flag = true;
                    r -= 10;
                }
                result.insert(0, r);
            }
        }
        if (flag) {
            result.insert(0, 1);
        }
        return result.toString();
    }


发表于 2021-03-01 14:34:02 回复(0)
char* solve(char* s, char* t ) {
    // write code here
    int s_len,t_len,max_len,min_len,i,j,sum=0,temp=0;
	s_len = strlen(s);
	t_len = strlen(t);
	j=max_len = s_len>t_len ? s_len:t_len;
	min_len = s_len<t_len ? s_len:t_len;
	char *result ;
    result =(char *) malloc(sizeof(char)*(max_len+1));
	while(s_len>0 && t_len>0){
		sum = (int)(s[s_len-1]-'0' )+ (int)(t[t_len-1]-'0') + temp;
		result[max_len] = (char)(sum%10) + '0';
	//	printf("%c ",result[max_len]);
		temp = sum/10;
		
		s_len--;
		t_len--;
		max_len--;
	}
	while(s_len>0){
		sum = (int)(s[s_len-1]-'0' )+  temp;
		result[max_len] = (char)(sum%10) + '0';
		temp = sum/10;
		
		s_len--;
		max_len--;
	}
	while(t_len>0){
		sum =(int)(t[t_len-1]-'0') + temp;
		result[max_len] = (char)(sum%10) + '0';
		temp = sum/10;
		
		t_len--;
		max_len--;
	}
	result[0]= (char)(temp)+'0';
	if(result[0]=='0'){
		for(i=0;i<j;i++){
			result[i]=result[i+1]; 
		}
		result[j]='\0';
	}
	return result;
}

实在找不出为啥测试用例通过率不是100%了 有大佬可以路过瞅两眼嘛
发表于 2021-02-26 21:27:52 回复(0)
使用栈,第一个字符串由尾部向前一个一个压入栈,和第二个相对应位做加法,超过十留下个位,十位再次压入栈计算
发表于 2021-02-25 20:30:26 回复(0)
import java.util.*;
import java.math.BigDecimal;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public String solve (String s, String t) {
        BigDecimal b1=new BigDecimal(s);
        BigDecimal b2=new BigDecimal(t);
        BigDecimal b3=b1.add(b2);
        String num = b3.toString();
        return num;
    }
}
java是面向对象的  找个对象用
发表于 2021-02-24 17:56:14 回复(0)
string solve(string s, string t) {
        // write code here
        string ans = "";
        reverse(s.begin(), s.end());
        reverse(t.begin(), t.end());
        int c = 0;
        int sum = 0;
        for(int i=0;i<s.size()||i<t.size();i++){
            sum = c;
            if(i<s.size()) sum += s[i]-'0';
            if(i<t.size()) sum += t[i]-'0';
            ans += (sum % 10) +'0';
            c = sum/10;
        }
        if(c) ans+='1';
        reverse(ans.begin(), ans.end());
        return ans;
    }
比较奇怪的是,如果for循环的终止条件如下,则无法通过最后一个用例:
for(int i=0;s[i]!=0||t[i]!=0;i++){
    sum = c;
    if(s[i]!=0) sum += s[i]-'0';
    if(t[i]!=0) sum += t[i]-'0';
    ans += (sum % 10) +'0';
    c = sum/10;
}
希望有大神能指导解惑~


发表于 2021-02-21 10:57:49 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */

    string solve(string s, string t) {
        // write code here
        int i=s.size()-1;
        int j=t.size()-1;
        string ans;
        int curr=0;
        while(i>=0 || j>=0 || curr)
        {
            int a=i>=0?s[i]-'0':0;
            int b=j>=0?t[j]-'0':0;
            int res=a+b+curr;
            curr=res/10;
            ans=ans.insert(0,to_string(res%10));
            i--;
            j--;
        }
        return ans;
    }
};

发表于 2021-02-15 17:43:25 回复(0)
//求求大佬帮我看一下为什么只通过了80%,有什么情况我没有考虑到
//我的思路是把两个字符串分割形成字符串数组后长度补齐,逐位相加,进位加一
function solve( s ,  t ) {
    var c=0;
    var sum=[];
    var srr=s.split("");
    var trr=t.split("");
    if(srr.length<=trr.length){
        for(var i=0;i<trr.length-srr.length;i++){
            srr.unshift('0');
        }
    }
    else{
        for(var i=0;i<srr.length-trr.length;i++){
            trr.unshift('0');
        }
    }
    for(var i=srr.length-1;i>=0;i--){
        sum[i]=Number(srr[i])+Number(trr[i])+c;
        c=0;
        if(i!=0&&sum[i]>9){
            c=Math.floor(sum[i]/10);
            sum[i] = sum[i]-10;
        }
    }
    return sum.join("");
}
module.exports = {
    solve : solve
};
发表于 2021-02-14 22:07:49 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        // write code here
        string result = "";
        int carry = 0, temp;
        int len1 = s.size(),  len2 = t.size();
        while(len1 && len2)
        {
            temp = (s[--len1] - '0') + (t[--len2] - '0') + carry;
            carry = temp/10;
            temp = temp%10;
            result = to_string(temp) + result;
        }
        if(len1)
            while(len1)
            {
                temp = (s[--len1] - '0') + carry;
                carry = temp /10;
                temp = temp%10;
                result = to_string(temp) + result;
            }
        if(len2)
            while(len2)
            {
                temp = (t[--len2] - '0') + carry;
                carry = temp /10;
                temp = temp%10;
                result = to_string(temp) + result;
            }
        if(carry)
            result = to_string(carry) + result;
        return result;
    }
};

发表于 2021-02-09 13:49:34 回复(0)
对比->“实际输出和预期输出是一致的”,然而并不能通过。
发表于 2021-02-09 11:11:48 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        // write code here
        string res;
        
        if (s.empty()) return t;
        if (t.empty()) return s;
        
        reverse(s.begin(),s.end());
        reverse(t.begin(),t.end());
        
        int size1 = s.size();
        int size2 = t.size();
        
        int c = 0;
        for (int i = 0;i < max(size1, size2);i++) {
            int tmp = (s[i] - '0')+ (t[i] - '0') + c;
            c = tmp /10;
            res += (tmp%10 + '0');
        }
        if (c > 0)
            res += (c + '0');      
        reverse(res.begin(), res.end());
        return res;
    }
};
求助,为什么有一个用例过不了,但是显示的那个用例显示我的答案和预期是一样的
发表于 2021-02-08 09:23:44 回复(0)
可以得到结果,但是提交显示错误,有没有大佬看看为什么不行。
import java.util.Scanner;

public class Solution {
    public String solve (String s, String t) {
        int a1=toInt(s)+toInt(t);
        String a2=toString(a1);
        return a2;
    }
    static int toInt(String str){
        int i=Integer.parseInt(str);
        return i;
    }
    static String toString(int i){
        String str=String.valueOf(i);
        return str;
    }
}

class test{
    public static void main(String[] args) {
        Solution solution=new Solution();
        Scanner sc=new Scanner(System.in);
        String s1=sc.next();
        String s2=sc.next();
        System.out.println("\""+solution.solve(s1,s2)+"\"");
    }
}

发表于 2021-02-06 20:59:31 回复(0)