大整数乘法实现思路

1、大整数乘法的实现思路(一):模拟手工列竖式计算两个大整数的乘积

  • 模拟手工计算两个整数相乘的过程:逐位相乘,错位累加,最后进位。以 1235789×6452351 1235789 × 6452351 为例:

    • 相乘的前提: 被乘数位数 >= 乘数位数。 x×y x × y 的逐位相乘次数取决于乘数y的位数。
      • 低位补0:乘数y从十位数开始乘以被乘数的每位时,相乘后的结果的低位要补足相应0的数目,例如:从十位开始,则需要补个位的0;从百位开始,则需要补十位和个位的0,诸如此类。
      • 高位补0:m位的被乘数x和n位的乘数y相乘,最终累加和的位数为:m+n-1,所以相乘后的结果的高位也要补足相应的0的数目,例如:乘数6452351的十位乘以被乘数1235789的每位时,算上低位补的0,数组中一共是8位,所以乘积结果需要在高位补0:(7+7-1)-8=5个。
    • 乘数的每位和被乘数的每位逐位相乘,每次相乘结果如下:

      10的幂  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12]
      第一次: [9, 8, 7, 5, 3, 2, 1, 0, 0, 0, 0, 0,0]
      第二次: [0,45,40,35, 25,15, 10, 5, 0, 0, 0, 0,0]
      第三次: [0, 0,27,24, 21,15, 9, 6, 3, 0, 0, 0,0]
      第四次: [0, 0, 0,18, 16,14, 10, 6, 4, 2, 0, 0,0]
      第五次: [0, 0, 0, 0, 45,40, 35, 25,15,10, 5, 0,0]
      第六次: [0, 0, 0, 0, 0,36, 32, 28,20,12, 8, 4,0]
      第七次: [0, 0, 0, 0, 0, 0, 54, 48,42,30,18,12,6]
      逐位累加:[9,53,74,82,110,122,151,118,84,54,31,16,6]
    • 进位:除了最高位,每位逢十进一,本位只留一个数字。
      [9,53,74,82,110,122,151,118,84,54,31,16,6]进位结果:[9, 3, 9, 9, 8, 3, 4, 4, 7, 3, 7, 9, 7]

  • 上述大整数相乘思路的代码实现(java):
package com.nwnu.algorithm.divide_and_conquer.bigInteger_multiply;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;

/** * @Author gaoyF * @Date 2018/7/3 9:28 * @Description 任意大整数相乘 */
public class BigIntegerMultiply {
    public static void main(String[] args) {

        System.out.print("被乘数:");
        Scanner sc_a = new Scanner(System.in);
        String x_a = sc_a.nextLine();

        System.out.print("乘数:");
        Scanner sc_b = new Scanner(System.in);
        String x_b = sc_b.nextLine();

        //调用multiply()方法计算两个大整数的乘积
        String result = multiply_v1(x_a,x_b);
        System.out.printf("multiply 乘积:%s",result);
        System.out.println('\r');

        //计算结果正误验证
        BigInteger bi_x_a = new BigInteger(x_a);
        BigInteger bi_x_b = new BigInteger(x_b);
        System.out.printf("bigInteger 乘积:%s",bi_x_a.multiply(bi_x_b));
    }

    /** * 模拟手工计算大整数相乘的过程:逐位相乘,然后再进位 * @param x_a 被乘数 * @param x_b 乘数 * @return */
    public static String multiply_v1(String x_a,String x_b) {
        /** * 始终保证被乘数的位数大于乘数的位数 */
        if (x_a.length() < x_b.length()) {
            String x_t = x_a;
            x_a = x_b;
            x_b = x_t;
        }
        /** * 将字符串形式的被乘数和乘数解析至列表al_a/al_b,并倒序存储 */
        ArrayList<Character> al_a = new ArrayList<>();
        ArrayList<Character> al_b = new ArrayList<>();
        ArrayList<Integer> al_z = new ArrayList<>(); //al_z用来存储被乘数和乘数各位乘积的累加和
        for (int i = 0; i < x_a.length() + x_b.length()-1; i++) {
            al_z.add(0);
        }
        for (int i = x_a.length()-1; i >= 0 ; i--) {
            al_a.add(x_a.charAt(i));
        }
        for (int i = x_b.length()-1; i >= 0 ; i--) {
            al_b.add(x_b.charAt(i));
        }
// System.out.println(al_a);
// System.out.println(al_b);
        /** * 被乘数和乘数累积和计算 */
        for (int i = 0; i < al_b.size(); i++) {
            ArrayList<Integer> al_y = new ArrayList<>(); //al_y用于存储每次累乘完后的结果
            //低位补0
            if (i != 0) {
                for (int k = 0; k < i; k++) {
                    al_y.add(0);
                }
            }
            for (int j = 0; j < al_a.size(); j++) {
                //ASCII码值相减,获得字符数字表示的整型数字
                al_y.add(((int)al_a.get(j).charValue()-(int)('0')) * ((int)al_b.get(i).charValue()-(int)('0')));
            }
            //高位补0
            if (al_y.size() != al_z.size()) {
                for (int k = al_y.size(); k < al_z.size(); k++) {
                    al_y.add(0);
                }
            }
// System.out.println(al_y);
            //累加和
            for (int k = 0; k < al_y.size(); k++) {
                al_z.set(k,al_y.get(k) + al_z.get(k));
            }
        }
// System.out.println(al_z);
        /** * 进位处理 */
        for (int i = 0; i < al_z.size()-1; i++) {
            if (al_z.get(i) >= 10) {
                al_z.set(i+1,al_z.get(i+1) + al_z.get(i)/10);
                al_z.set(i,al_z.get(i)%10);
            }
        }
// System.out.println(al_z);
        /** * 返回乘积结果 */
        String value = "";
        for (int i = al_z.size()-1; i >= 0 ; i--) {
            value = value.concat(al_z.get(i).toString());
// System.out.println(value);
        }
        return value;
    }
}
    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/u010970879/article/details/80894431
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞