大整数相乘java_大整数乘法—java实现

大整数相乘java_大整数乘法—java实现大整数相乘参考博客:https://blog.csdn.net/oh_maxy/article/details/10903929https://blog.csdn.net/u010867294/article/details/77482306大整数相乘,对于计算机来说,由于整数的范围存在限制,如果数值太大,则两个较大整数及其结果在表示时就将可能产生溢出。因此,对于两个大整数的乘法我们就需要将其转化…

大家好,又见面了,我是你们的朋友全栈君。

大整数相乘

参考博客:

https://blog.csdn.net/oh_maxy/article/details/10903929

https://blog.csdn.net/u010867294/article/details/77482306

大整数相乘,对于计算机来说,由于整数的范围存在限制,如果数值太大,则两个较大整数及其结果在表示时就将可能产生溢出。因此,对于两个大整数的乘法我们就需要将其转化为字符串来进行求解。

分治法实现大整数相乘—算法思想:

当我们输入两个大整数num1,num2,长度分别为n,m,计算机无法直接计算其结果,采用分而治之的思想,我们可以分别将两个数均分为四个部分,记作A,B,C,D,其中:

A为num1的前n/2,

B为num1的后n/2,

C为num2的前m/2

D为num2的后m/2

至此,我们有:

num1 * num2 = (A * 10^(n/2) + B) * (C * 10^(m/2) + D)= AC * 10实现代码:

import java.util.*;

import static java.util.Collections.reverse;

/**

* @author

* @date 2020/10/1 – 20:55

*/

public class DivideMultiply {

public static void main(String[] args) {

int aLen, bLen;

Scanner scanner = new Scanner(System.in);

System.out.println(“请输入一个长整数x:”);

String as = scanner.nextLine();

System.out.println(“请输入另一个长整数y:”);

String bs = scanner.nextLine();

aLen = as.length();

bLen = bs.length();

List an = new ArrayList<>();

List bn = new ArrayList<>();

List cn;

//数字存入集合

for (int i = 0; i < aLen; i++) {

an.add(as.charAt(i) – ‘0’);

}

for (int i = 0; i < bLen; i++) {

bn.add(bs.charAt(i) – ‘0’);

}

cn = divideMultiply(an, bn, 0, 0);

//求得结果显示

for (Integer i : cn) {

System.out.print(i);

}

}

//求大整数相乘

public static List divideMultiply(List an, List bn, int x, int y) {

int al = an.size();

int bl = bn.size();

int ax = x;

int by = y;

if (al == 1) { //当递归到存在数据长度为1的值时进行乘法运算,结束递归

return multiply(bn, an, x, y);

}

if (bl == 1) {

return multiply(an, bn, x, y);

}

x = x + al – al / 2;

y = y + bl – bl / 2;

List a = getList(an, 0, al / 2); //将大整数分为四个小整数

List b = getList(an, al / 2, al);

List c = getList(bn, 0, bl / 2);

List d = getList(bn, bl / 2, bl);

List ac = divideMultiply(a, c, x, y); //递归求得ac,ad,bc,cd的值

List ad = divideMultiply(a, d, x, by);

d = getList(bn, bl / 2, bl);

List bc = divideMultiply(b, c, ax, y);

b = getList(an, al / 2, al);

List bd = divideMultiply(b, d, ax, by);

return add(ac, ad, bc, bd);

}

//分治后两数相乘

public static List multiply(List an, List bn, int x, int y) {

List result = new ArrayList<>();

int len;

reverse(an);

for (int i = 0; i <= an.size(); i++) { //首先将相乘结果全部置零

result.add(0);

}

for (int i = 0; i < an.size(); i++) {

result.set(i, result.get(i) + an.get(i) * bn.get(0)); //将相乘的值存入返回值

result.set(i + 1, result.get(i + 1) + result.get(i) / 10); //若相乘的值大于10,则进位

result.set(i, result.get(i) % 10); //进位后留余

}

len = result.size(); //如果返回结果后面还剩余0,则将零去掉

while (result.get(len – 1) == 0 && len > 1) {

result.remove(len – 1);

len–;

}

reverse(result); //将所得解逆置即为乘法所得

int l = x + y; //由于两数相乘时可能有10的幂,所以在结果后补0

while (l > 0) {

result.add(0);

l–;

}

return result;

}

//相乘的结果相加

public static List add(List ac, List ad, List bc, List bd) {

Collections.reverse(ac);

Collections.reverse(ad);

Collections.reverse(bc);

Collections.reverse(bd);

List result = new ArrayList<>();

int len = ac.size() + bc.size() + ad.size() + bd.size();

for (int i = 0; i <= len; i++) {

result.add(0);

}

for (int i = 0; i < ac.size(); i++) {

result.set(i, ac.get(i));

}

for (int i = 0; i < ad.size(); i++) {

result.set(i, result.get(i) + ad.get(i));

}

for (int i = 0; i < bc.size(); i++) {

result.set(i, result.get(i) + bc.get(i));

}

for (int i = 0; i < bd.size(); i++) {

result.set(i, result.get(i) + bd.get(i));

}

for (int i = 0; i < len; i++) {

result.set(i + 1, result.get(i + 1) + result.get(i) / 10);

result.set(i, result.get(i) % 10);

}

while (result.get(len) == 0 && len > 1) {

result.remove(len);

len–;

}

Collections.reverse(result);

return result;

}

//获取集合中的某一部分

public static List getList(List list, int x, int y) {

List list1 = new ArrayList<>();

for (int i = x; i < y; i++) {

list1.add(list.get(i));

}

return list1;

}

}

时间复杂度分析:

该问题类似的将两个大的数相乘转化为了四个小的数相乘,由此可以得出公式,其中字符串转化位集合时间复杂度为n,字符串实现乘法时间复杂度为n,字符串相加,时间复杂度为n,得:

T(n) = 4T(n/2)+3n

由Master定理可得:

a=4,b=2,f(n)=3n,n(logb(a))=O(n2)

因为f(n)=3n=O(n^(logb(a)-c)),得c=1,

所以T(n) = O(n(logb(a)))=O(n2),

(m+n)/2 ↩︎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137133.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月2日 下午2:46
下一篇 2022年6月2日 下午2:46


相关推荐

  • 科大讯飞讯飞星火X1全面升级,国产AI大模型实力再上新台阶

    科大讯飞讯飞星火X1全面升级,国产AI大模型实力再上新台阶

    2026年3月14日
    2
  • python中setdefault_python练习之setdefault用法详解

    python中setdefault_python练习之setdefault用法详解setdefault 作为 python 字典中的函数 有很多功能 语法 dict setdefault key default None key 为查找的键 default 为查不到时 系统自动在字典里生成的与 key 对应的值 如果存在该键值对 则返回对应的值 否则返回 default 的参数用法 给字典中的不存在的键赋值为 default 的参数 gt gt gt spam name

    2026年3月19日
    2
  • MATLAB入门教程

    MATLAB入门教程MATLAB入门教程

    2022年8月2日
    9
  • 最短路径——Dijkstra算法和Floyd算法

    最短路径——Dijkstra算法和Floyd算法一 Dijkstra 算法 1 单源点的最短路径问题 给定带权有向图 G 和源点 v 求从 v 到 G 中其余各顶点的最短路径 我们用一个例子来具体说明迪杰斯特拉算法的流程 定义源点为 0 dist i 为源点 0 到顶点 i 的最短路径 其过程描述如下 步骤 dist 1 dist 2 dist 3 dist 4 已找到的集合第 1 步 8

    2026年3月16日
    2
  • 编程之美2013初赛——竞价

    编程之美2013初赛——竞价题目时间限制 1000ms 内存限制 256MB 描述 Alice 和 Bob 都要向同一个商人购买钻石 商人手中有 N 颗钻石 他会将它们一颗颗地卖给他们 Alice 和 Bob 通过竞价的方式来决定钻石的归属 具体的过程如下 商人首先指定其中一个人开始报价 之后两人轮流报价 要求是一定要比对方报的价格更高 任何时候 如果一个人不愿出价或者出不起价钱时 可以宣布弃权 则对手以最后一次

    2026年3月19日
    2
  • git的版本回退教程(带你一步一步操作)

    git的版本回退教程(带你一步一步操作)nbsp nbsp 在之前的文章中我们已经学会了如何使用 git 提交文件 下载更新文件 那么在 git 中如何进行版本回退呐 nbsp 首先 在本地建立一个 git 项目 并且与远程服务端 github 上的项目进行关联 如果这一步骤有问题的童靴 请参考我的上一篇文章 害羞 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 1 第一次建立 git 项目 提交到远程分支 并且记录为第一个版本 nbsp nbsp

    2026年3月18日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号