笔试狂刷--Day2(模拟高精度算法)

大家好,我是LvZi,今天带来笔试狂刷--Day2(模拟高精度算法)
在这里插入图片描述

一.二进制求和

题目链接:二进制求和
分析:
在这里插入图片描述

代码实现:

class Solution {
    public String addBinary(String a, String b) {
        int c1 = a.length() - 1, c2 = b.length() - 1, t = 0;
        StringBuffer ret = new StringBuffer();

        while(c1 >=0 || c2 >= 0 || t != 0) {
            if(c1 >= 0) t += a.charAt(c1--) - '0';// 保证不为空
            if(c2 >= 0) t += b.charAt(c2--) - '0';// 保证不为空

            char ch = (char)((t % 2) + '0');
            ret.append(ch);
            t /= 2;// 存储进位
        }

        
        return ret.reverse().toString();
    }
}

二.大数相加(十进制求和)

大数相加(十进制求和)

代码实现:
1.模拟

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public String solve (String a, String b) {
        // write code here
        int c1 = a.length() - 1, c2 = b.length() - 1, t = 0;
        StringBuffer ret = new StringBuffer();

        while(c1 >=0 || c2 >= 0 || t != 0) {
            if(c1 >= 0) t += a.charAt(c1--) - '0';// 保证不为空
            if(c2 >= 0) t += b.charAt(c2--) - '0';// 保证不为空

            char ch = (char)((t % 10) + '0');
            ret.append(ch);
            t /= 10;// 存储进位
        }

        
        return ret.reverse().toString();
    }
}

2.使用Java内置的BigInteger

import java.util.*;
import java.math.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    public String solve (String s, String t) {
        // write code here
        BigInteger a = new BigInteger(s);
        BigInteger b = new BigInteger(t);
        BigInteger ret = a.add(b);

        return ret.toString();
    }
}

三.大数乘法

大数乘法
分析:
在这里插入图片描述

代码实现:
1.

import java.util.*;
import java.math.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串 第一个整数
     * @param t string字符串 第二个整数
     * @return string字符串
     */
    public String solve (String ss, String tt) {
        // write code here
        char[] s = new StringBuffer(ss).reverse().toString().toCharArray();
        char[] t = new StringBuffer(tt).reverse().toString().toCharArray();
        int n = s.length, m = t.length;
        int[] tmp = new int[m + n];

        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++) 
                tmp[i + j] += (s[i] - '0') * (t[j] - '0');

        // 模拟加法
        int c = 0;
        StringBuffer ret = new StringBuffer();
        for(int x : tmp) {
            c += x;
            ret.append((char)(c % 10 + '0'));
            c /= 10;
        }

        // 处理前导零
        while(ret.length() > 1 && ret.charAt(ret.length() - 1) == '0') {
            ret.deleteCharAt(ret.length() - 1);
        }

        return ret.reverse().toString();
    }
}

2.使用BigInteger

import java.util.*;
import java.math.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串 第一个整数
     * @param t string字符串 第二个整数
     * @return string字符串
     */
    public String solve (String s, String t) {
        // write code here
        BigInteger a = new BigInteger(s);
        BigInteger b = new BigInteger(t);
        BigInteger ret = a.multiply(b);

        return ret.toString();
    }
}

四.两数相加I(链表)

题目链接:两数相加I
代码实现:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        ListNode cur1 = l1;
        ListNode cur2 = l2;
        ListNode phead = new ListNode(0);
        ListNode cur = phead;// 用于尾插

        int t = 0;// 用于表示本次相加的结果  处理进位

        // 要注意t最后可能不为0 要进一位
        while(cur1 != null || cur2 != null || t != 0) {
            // 加上第一个节点
            if(cur1 != null) {
                t += cur1.val;
                cur1 = cur1.next;
            }

            // 加上第二个节点
            if(cur2 != null) {
                t += cur2.val;
                cur2 = cur2.next;
            }

            ListNode newNode = new ListNode(t % 10);
            t /= 10;

            // 尾插
            cur.next = newNode;
            cur = newNode;
        }
        return phead.next;
    }
}

五.两数相加II(链表逆序)

题目链接:两数相加II(链表逆序)
代码实现:

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head1 ListNode类
     * @param head2 ListNode类
     * @return ListNode类
     */
    public ListNode addInList (ListNode head11, ListNode head22) {
        // write code here
        ListNode h1 = reverse(head11), h2 = reverse(head22), ret = new ListNode(0), phead = ret;
        ListNode c1 = h1, c2 = h2;
        int t = 0;

        while (c1 != null || c2 != null || t != 0) {
            if (c1 != null) {
                t += c1.val;
                c1 = c1.next;
            }
            if (c2 != null) {
                t += c2.val;
                c2 = c2.next;
            }

            ListNode tmp = new ListNode(t % 10);
            t /= 10;
            
            phead.next = tmp;
            phead = phead.next;
        }

        // 逆序最后的结果
        return reverse(ret.next);
    }

    // 逆序链表
    private ListNode reverse(ListNode head) {
        ListNode phead = new ListNode(0), cur = head;

        while (cur != null) {
            ListNode curNext = cur.next;

            cur.next = phead.next;
            phead.next = cur;

            cur = curNext;
        }
        return phead.next;
    }
}

总结:

  1. 高精度算法本质上就是模拟竖式运算,高精度加法通过变量t和进制来确定每次相加的结果和保存响应的进位;高精度乘法实际上是模拟了无进位相乘再相加的过程,使用数组保存当前位置结果的总和,最后再对整个数组模拟十进制相加即可(注意可能的前导0)
  2. 注意模拟过程中的顺序,需要从最低位开始模拟,以及注意最后的返回结果(有的需要逆序)
  3. 在Java中,如果涉及到高进度的加减法,可以使用自带的BigInteger
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值