算法-大数相乘

这篇具有很好参考价值的文章主要介绍了算法-大数相乘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解决算法;
*  1. 模拟小学乘法:最简单的乘法竖式手算的累加型;
*  2. 分治乘法:最简单的是Karatsuba乘法,一般化以后有Toom-Cook乘法;
*  3. 快速傅里叶变换FFT:(为了避免精度问题,可以改用快速数论变换FNTT),时间复杂度O(N lgN lglgN)。具体可参照Schönhage–Strassen algorithm;
*  4. 中国剩余定理:把每个数分解到一些互素的模上,然后每个同余方程对应乘起来就行;
*  5. Furer’s algorithm:在渐进意义上FNTT还快的算法。不过好像不太实用,本文就不作介绍了。大家可以参考维基百科Fürer’s algorithm

参考地址:https://blog.csdn.net/u010983881/article/details/77503519

1. 小学乘法代码如下:

/**
     * 模拟小学乘法
     */
    public static String primaryMul(String str1, String str2){
        System.out.println("start primaryMul param=" + str1 + "," + str2 + ";time=" + System.currentTimeMillis());
        int[] int1 = string2IntArray(str1);
        int[] int2 = string2IntArray(str2);
        List<Integer> result = new ArrayList<>();
        for (int i = int1.length-1; i >=0 ; i--) {
            List<Integer> tempList = new ArrayList<>();
            int ten = 0;
            for (int j = int2.length-1; j >=0 ; j--) {
                int a = int1[i] * int2[j] + ten;
                ten = a / 10;
                tempList.add(a % 10);
            }
            if (ten > 0){
                tempList.add(ten);
            }
            //两行相加
            int carry = 0;
            for (int j = 0; j < tempList.size(); j++) {
                int r1 = 0;
                int index = j + (int1.length-1-i);
                if (index < 0 | result.size() > index){
                    r1 = result.get(index);
                }
                int a = tempList.get(j) + r1 + carry;
                carry = a / 10;
                if (index < 0 | result.size() > index){
                    result.set(index, a % 10);
                }else{
                    result.add(a % 10);
                }
            }
            if (carry > 0){
                result.add(carry);
            }
        }
        //方向旋转
        int copy;
        for (int i = 0; i < result.size(); i++) {
            if (i < result.size() / 2){
                copy = result.get(i);
                int index = result.size() -1 -i;
                result.set(i, result.get(index));
                result.set(index, copy);
            }
        }
        StringBuilder sb = new StringBuilder();
        for (Integer integer : result) {
            sb.append(integer);
        }
        System.out.println("end primaryMul result=" + sb + ";time=" + System.currentTimeMillis());
        return sb.toString();
    }

    public static int[] string2IntArray(String str){
        String[] strs = str.split("");
        int[] ret = new int[strs.length];
        for (int i = 0; i < strs.length; i++) {
            ret[i] = Integer.parseInt(strs[i]);
        }
        return ret;
    }

2. 小学算法-累加算法

 

/**
     * 模拟小学乘法 - 累加算法
     */
    private static String accumul(String str1, String str2){
        System.out.println("start accumul param=" + str1 + "," + str2 + ";time=" + System.currentTimeMillis());
        int[] int1 = string2IntArray(str1);
        int[] int2 = string2IntArray(str2);
        int[] result = new int[int1.length + int2.length];
        for (int i = 0; i < int1.length; i++) {
            for (int j = 0; j < int2.length; j++) {
                result[i + j + 1] += int1[i] * int2[j];
            }
        }
        for (int i = result.length - 1; i >= 0; i--) {
            if (result[i] >= 10){
                result[i-1] += result[i] / 10;
                result[i] = result[i] % 10;
            }
        }
        StringBuilder sb = new StringBuilder();
        for (Integer integer : result) {
            sb.append(integer);
        }
        System.out.println("end accumul result=" + sb + ";time=" + System.currentTimeMillis());
        return sb.toString();
    }

3. 分治算法-Karatsuba文章来源地址https://www.toymoban.com/news/detail-819398.html

/**
 * Karatsuba乘法
 */
public static long karatsuba(long num1, long num2){
    //递归终止条件
    if(num1 < 10 || num2 < 10) return num1 * num2;

    // 计算拆分长度
    int size1 = String.valueOf(num1).length();
    int size2 = String.valueOf(num2).length();
    int halfN = Math.max(size1, size2) / 2;

    /* 拆分为a, b, c, d */
    long a = Long.valueOf(String.valueOf(num1).substring(0, size1 - halfN));
    long b = Long.valueOf(String.valueOf(num1).substring(size1 - halfN));
    long c = Long.valueOf(String.valueOf(num2).substring(0, size2 - halfN));
    long d = Long.valueOf(String.valueOf(num2).substring(size2 - halfN));

    // 计算z2, z0, z1, 此处的乘法使用递归
    long z2 = karatsuba(a, c);
    long z0 = karatsuba(b, d);
    long z1 = karatsuba((a + b), (c + d)) - z0 - z2;

    return (long)(z2 * Math.pow(10, (2*halfN)) + z1 * Math.pow(10, halfN) + z0);
}

到了这里,关于算法-大数相乘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 「算法小记」-2:矩阵链相乘的方案数【迭代/递归/动态规划/区域化DP/记忆化搜索】(C++ )

    「算法小记」-2:矩阵链相乘的方案数【迭代/递归/动态规划/区域化DP/记忆化搜索】(C++ )

    😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号:程序员洲洲。 🎈 本文专栏:本文收录于洲洲的《算法小记》系列专栏,该专栏记录了许

    2024年02月05日
    浏览(12)
  • 大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类

    大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类

    针对模型的拟合,这里引入两个概念:过拟合,欠拟合。 过拟合:在机器学习任务中,我们通常将数据集分为两部分:训练集和测试集。训练集用于训练模型,而测试集则用于评估模型在未见过数据上的性能。过拟合就是指模型在训练集上表现较好,但在测试集上表现较差的

    2024年02月04日
    浏览(30)
  • 大数据机器学习深度解读决策树算法:技术全解与案例实战

    大数据机器学习深度解读决策树算法:技术全解与案例实战

    本文深入探讨了机器学习中的决策树算法,从基础概念到高级研究进展,再到实战案例应用,全面解析了决策树的理论及其在现实世界问题中的实际效能。通过技术细节和案例实践,揭示了决策树在提供可解释预测中的独特价值。 决策树算法是机器学习领域的基石之一,其强

    2024年02月04日
    浏览(19)
  • C++两个矩阵相乘代码(内附有矩阵相乘的条件与规则,以及对代码的详细解答)

         再复制粘贴代码之前可以先了解学习一下什么是矩阵相乘,矩阵相乘的条件与规则又是什么。 点击一下链接即可进入学习:                       #矩阵相乘的学习链接          以下是两个矩阵相乘的代码块(输入版) 补充①:对于for循环了解还不够透彻的可以进

    2024年02月11日
    浏览(11)
  • 矩阵和向量如何相乘?

    矩阵和向量如何相乘?

    矩阵与向量相乘遵循特定的数学规则,这个过程通常被称为矩阵向量乘法。在进行矩阵向量乘法时,矩阵的列数必须与向量的行数相同。以下是一个具体的例子: 例子: 假设我们有一个矩阵 A 和一个向量 v,其中: 在这个例子中,矩阵 A 是一个 3x2 矩阵(3行2列),向量v 是

    2024年01月22日
    浏览(6)
  • 14-矩阵相乘及其运算法则

    14-矩阵相乘及其运算法则

    矩阵与向量的乘法 在这一篇文章中我们就将基于上一篇重新审视矩阵的这个视点来理解矩阵的乘法,那么在这一篇,我们主要来看一下矩阵和向量的乘法。这里这个线性方程组是上一小节给大家举的模拟的一个非常简单的小型经济系统的例子,我们可以把这个经济系统其实本

    2024年02月13日
    浏览(10)
  • 矩阵和矩阵如何相乘?

    矩阵和矩阵如何相乘?

    矩阵与矩阵相乘遵循特定的数学规则。为了相乘,第一个矩阵的列数必须等于第二个矩阵的行数。矩阵乘法的结果是一个新矩阵,其行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。矩阵乘法不满足交换律,即 AB≠BA。 例子: 假设我们有两个矩阵 A 和 B,其中: 在这

    2024年01月22日
    浏览(17)
  • 特征图拼接、相加和相乘

      特征图拼接、相加和相乘是在神经网络中进行特征融合的不同方式,它们各自有不同的优缺点,适用于不同的场景。下面我会分别解释它们的数学原理和代码示例,并讨论它们的优缺点和适用场景。 特征图拼接(Concatenation):   特征图拼接是将多个特征图在通道维度

    2024年02月13日
    浏览(104)
  • 动态规划--矩阵链相乘问题

    动态规划--矩阵链相乘问题

    明确原始问题A[1:n]: 计算矩阵链 所需的 最小乘法次数。 (1)是否满足最优子结构,问题的解是否包含子问题的优化解? 若计算A[1:n]的优化顺序在 k 处断开矩阵链,即A[1:n]=A[1:k]×A[k+1:n],则在A[1:n]的优化顺序中,对应于子问题A[1:k]的解必须是A[1:k]的优化解,对应A[k+1:n]的解必

    2024年01月25日
    浏览(10)
  • 矩阵链相乘(动态规划法)

    矩阵链相乘(动态规划法)

    矩阵链乘法是耳熟能详的问题了,有很多矩阵,排列成矩阵链,矩阵链的要求是相邻的两个是可以相乘的,可以相乘是有条件的,两个矩阵能够相乘的条件就是行、列之间是有关系的,两个矩阵如果能够相乘,就是前面矩阵的列号和后面矩阵的行号是一致的。 如何确定矩阵的

    2024年02月09日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包