zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

大数加法

2023-02-18 16:36:15 时间

题目:

 

 

 

思路:

先是说一说对这道题的理解吧,对于数字运算,我们大都知道int是存在范围的,long也是有范围的,但是当面对数值超出范围的时候我们要怎么应对,大概就是这题的一个知识点吧。
其次这题也很明显存在暴力破解的办法,就是将两个字符串的一位取出,进行转义相加,然后存在进位情况。依次处理最后达到了得出相加之后的字符串。方法二明显会更符合简单思维一点,就是弄出三个数组,然后两个塞参数,一个塞相加之后的结果,最后将结果数组输出。
方法一明显是方法二的一种升华,减少了使用空间,通过条件循环,遍历空两个字符串,对于先遍历空的补零。然后操作完的塞进StringBuilder 里面。最后的出相加后的数值。
其次还有一种方法,就是截取字符串范围值,利用 int b=Integer.parseInt(s); 这种方式,如 int的取值范围为-2147483648到+-2147483648 ,那么如果我们取九个字符串转义成int类型然后两个int相加的话必然会在int的取值范围内,那么18个字符长度的字符串相加,我们是不是只要操作两次就可以了呢,是不是更加便捷。

代码示例:

import java.util.Arrays;
 
public class Solution {
 
    public static void main(String[] args) {
        String s = "0", t = "0";
        String result = solve2(s, t);
        System.out.println(result);
    }
 
    /**
     * 这一种方法相对第二种是一种升华,减少了开创的空间,
     * 都是从数字末端遍历,直至两个字符串都被遍历完,先遍历完的每次都会补上一个0
     * 其次还会检查最后是否存在了字符串都遍历完了但是存在进位问题的处理
     * 最后得出的字符串就像是第二种得出的结果数组一样的需要经过一次反转成为目标字符串
     *
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public static 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();
    }
 
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     *
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public static String solve2(String s, String t) {
        int num1 = s.length(), num2 = t.length();
        int maxNum = Math.max(num1, num2);
        int[] arr1 = new int[maxNum + 1];
        int[] arr2 = new int[maxNum + 1];
        int[] result_arr = new int[maxNum + 1];
        for (int i = 0; i < num1; i++) {
            arr1[i] = s.charAt(num1 - 1 - i) - '0';//针对字符转义成int类型
        }
        System.out.println(Arrays.toString(arr1));
        for (int i = 0; i < num2; i++) {
            arr2[i] = t.charAt(num2 - 1 - i) - '0';//针对字符转义成int类型
        }
        System.out.println(Arrays.toString(arr2));
        //进行数字的加减合并,从个位数往上相加,超过10就进一位。
        for (int i = 0; i < maxNum; i++) {
            int temp = result_arr[i] + arr1[i] + arr2[i];
            if (temp >= 10) { //十进一
                temp = temp - 10;
                result_arr[i + 1] = result_arr[i + 1] + 1;
            }
            result_arr[i] = temp;
        }
        System.out.println(Arrays.toString(result_arr));
 
        StringBuffer str = new StringBuffer();
        boolean is_top = false;
        //用于遍历结果数组,从末尾遍历到开头,要处理最末尾那些是0开头的数字,不能输出0098765,而是输出正确的98765
        for (int i = maxNum; i >= 0; i--) {
            //这是很重要的一种情况,就是极限值没有考虑到,卡了我好久,就是当两个字符串都是0的时候,应该输出0
            //但是上面会忽略也就是如果一直未false时就不会添加元素 所以我加了 && i != 0 这个条件
            if (!is_top && i != 0) { //当碰到第一个不为0的开头时就不断的往里面添加元素
                if (result_arr[i] == 0) {
                    continue;
                } else {
                    is_top = true;
                }
            }
            str.append(result_arr[i]);
        }
        if (!is_top) {
            //这是很重要的一种情况,就是极限值没有考虑到,卡了我好久,就是当两个字符串都是0的时候,应该输出0
            //但是上面会忽略也就是如果一直未false时就不会添加元素
 
        }
        return str.toString();
    }
}