大整数相乘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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vue 富文本存储_vue 富文本编辑器 项目实战用法「建议收藏」

    vue 富文本存储_vue 富文本编辑器 项目实战用法「建议收藏」1.挑个富文本编辑器首先针对自己项目的类型,确定自己要用啥编辑器。1.1wangeditor如果一般类似博客这种项目不需要花里胡哨的,功能也不要求贼多的,推荐一下wangeditor(点击跳转)。能覆盖基本上所有的常见操作,轻量化,开源,有中文文档。▽wangeditor效果图1.2tinyMCE如果需要复杂的编辑器,推荐tinyMCE(点击跳转),同样也非常简单和优雅,但是文档是英文的,配合…

    2022年10月14日
    0
  • 使用FastJSON 对Map/JSON/String 进行互转[通俗易懂]

    使用FastJSON 对Map/JSON/String 进行互转[通俗易懂]Fastjson是一个Java语言编写的高性能功能完善的JSON库,由阿里巴巴公司团队开发的主要特性主要体现在以下几个方面:1.高性能fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson。并且还超越了google的二进制协议protocolbuf。2.功能强大支持各种JDK类型。包括基本类型、JavaBean、Collection、Ma

    2022年6月20日
    137
  • java后端开发职责_工作职责和岗位职责有什么区别

    java后端开发职责_工作职责和岗位职责有什么区别java后台开发岗位职责:1.参与项目后端的设计、开发工作,承担核心功能模块的代码编写,确保项目进度和质量;2.参与开发人员codereview工作,并能提供性能优化、安全性建议;3.参与系统架构设计、接口规范制定、技术文档编写等。4.参与现有系统的优化改进。岗位要求:1.本科及以上学历,计算机相关专业优先,【扎实的数据结构/算法与编码能力】;2.JAVA基础扎实,1年及以上JAV…

    2025年5月27日
    0
  • 质量工具因果图_质量管理因果图例题

    质量工具因果图_质量管理因果图例题前言在项目中,我们经常需要用到不同的工具对项目质量进行评审。使用不同的质量工具可能得到的结果不太一样。下面简单说下项目中常用到的质量分析工具因果图。释义:什么是因果图因果图又称为石川图、Ishikawa或鱼骨图,它把影响质量诸因素之间的关系以树状图的方式表示出来,使人一目了然,便于分析原因并采取相应的措施。它是一种在问题发生后,寻找根本原因的一种方法。它取名石川图是因为它是由日

    2022年8月14日
    4
  • 干式电力变压器技术参数和要求_10kv变6kv变压器型号技术参数

    干式电力变压器技术参数和要求_10kv变6kv变压器型号技术参数TiKV关键性能参数及优化

    2022年9月2日
    4
  • springboot 事务回滚「建议收藏」

    springboot 事务回滚「建议收藏」springboot事务回滚springboot事务使用springboot事务使用**1.**只有在开启事务的方法中出现异常,才会自动回滚,需要在service的public方法上面加上@Transactional(rollbackFor=Exception.class),一旦程序出现异常,事务会自动回滚@Transactional(rollbackFor=Excepti…

    2022年6月1日
    37

发表回复

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

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