C#,《小白学程序》第二十六课:大数乘法(BigInteger Multiply)的Toom-Cook 3算法及源程序

凑数的,仅供参考。

1 文本格式

/// <summary>
/// 《小白学程序》第二十六课:大数(BigInteger)的Toom-Cook 3乘法
/// Toom-Cook 3-Way Multiplication
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static string toom_cook3_multiply(string a, string b)
{
    int n = Math.Max(a.Length, b.Length);
    int[] ra = string_to_digitals(a, n);
    int[] rb = string_to_digitals(b, n);
    toom_cook3_process_00(ra, rb, out int[] rz);
    toom_cook3_carry(rz, n * 2);
    return digitals_to_string(rz);
}

/// <summary>
/// 短数字的乘法(常规乘法,小学生算法)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="z"></param>
private static void toom_cook3_normal(int[] a, int[] b, ref int[] z)
{
    int n = a.Length;
    for (int j = 0; j < n; j++)
    {
        for (int i = 0; i < n; i++)
        {
            z[j + i] += a[i] * b[j];
        }
    }
}

/// <summary>
/// 完全按原始C++代码改写;运行成功;
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="z"></param>
private static void toom_cook3_process_01(int[] a, int[] b, out int[] z)
{
    int n = a.Length;
    int n1 = n * 1 / 3;
    int n2 = n * 2 / 3;
    int n3 = n * 3 / 3;
    int n4 = n * 4 / 3;

    z = new int[n * 2];
    if (n <= 9)
    {
        toom_cook3_normal(a, b, ref z);
        return;
    }

    // int *a0 = &a[0];
    // Multiplicand / right side array pointer
    int a0 = 0;
    // int *a1 = &a[tLen / 3];
    // Multiplicand / central array pointer
    int a1 = n1;
    // int *a2 = &a[tLen * 2/ 3];
    // Multiplicand / left side array pointer
    int a2 = n2;// n * 2 / 3;

    // int *b0 = &b[0];
    // Multiplier / right side array pointer
    int b0 = 0;
    // int *b1 = &b[tLen / 3];
    // Multiplier / central array pointer
    int b1 = n1;
    // int *b2 = &b[tLen * 2 / 3];
    // Multiplier / left side array pointer
    int b2 = n2;// n * 2 / 3;

    // int *c0 = &z[(tLen / 3) * 0];
    int[] c0 = new int[n2];
    int[] c1 = new int[n2];
    // int *c2 = &z[(tLen / 3) * 2];
    int[] c2 = new int[n2];
    int[] c3 = new int[n2];
    // int *c4 = &z[(tLen / 3) * 4];
    int[] c4 = new int[n2];

    int[] a_m2 = new int[n1];  // a(-2)
    int[] a_m1 = new int[n1];  // a(-1)
    int[] a_0 = new int[n1];   // a(0)
    int[] a_1 = new int[n1];   // a(1)
    int[] a_inf = new int[n1]; // a(inf)
    int[] b_m2 = new int[n1];  // b-2)
    int[] b_m1 = new int[n1];  // b-1)
    int[] b_0 = new int[n1];   // b(0)
    int[] b_1 = new int[n1];   // b(1)
    int[] b_inf = new int[n1]; // b(inf)

    // ==== a(-2) = 4 * a2 - 2 * a1 + a0, b(-2) = 4 * b2 - 2 * b1 + b0
    for (int i = 0; i < n1; i++)
    {
        a_m2[i] = (a[a2 + i] << 2) - (a[a1 + i] << 1) + a[a0 + i];
        b_m2[i] = (b[b2 + i] << 2) - (b[b1 + i] << 1) + b[b0 + i];
    }
    // ==== c(-2) = a(-2) * b(-2)
    toom_cook3_process_01(a_m2, b_m2, out int[] c_m2);

    // ==== a(-1) = a2 - a1 + a0, b(-1) = b2 - b1 + b0
    for (int i = 0; i < n1; i++)
    {
        a_m1[i] = a[a2 + i] - a[a1 + i] + a[a0 + i];
        b_m1[i] = b[b2 + i] - b[b1 + i] + b[b0 + i];
    }
    // ==== c(-1) = a(-1) * b(-1)
    toom_cook3_process_01(a_m1, b_m1, out int[] c_m1);

    // ==== a(0) = a0, b(0) = b0
    for (int i = 0; i < n1; i++)
    {
        a_0[i] = a[a0 + i];
        b_0[i] = b[b0 + i];
    }
    // ==== c(0) = a(0) * b(0)
    toom_cook3_process_01(a_0, b_0, out int[] c_0);

    // ==== a(1) = a2 + a1 + a0, b(1) = b2 + b1 + b0
    for (int i = 0; i < n1; i++)
    {
        a_1[i] = a[a2 + i] + a[a1 + i] + a[a0 + i];
        b_1[i] = b[b2 + i] + b[b1 + i] + b[b0 + i];
    }
    // ==== c(1) = a(1) * b(1)
    toom_cook3_process_01(a_1, b_1, out int[] c_1);

    // ==== a(inf) = a2, b(inf) = b2
    for (int i = 0; i < n1; i++)
    {
        a_inf[i] = a[a2 + i];
        b_inf[i] = b[b2 + i];
    }

    // ==== c(inf) = a(inf) * b(inf)
    toom_cook3_process_01(a_inf, b_inf, out int[] c_inf);

    // ==== c4 = 6 * c(inf) / 6
    for (int i = 0; i < n2; i++)
    {
        c4[i] = c_inf[i];
    }
    // ==== c3 = -c(-2) + 3 * c(-1) - 3 * c(0) + c(1) + 12 * c(inf) / 6
    for (int i = 0; i < n2; i++)
    {
        c3[i] = -c_m2[i];
        c3[i] += (c_m1[i] << 1) + c_m1[i];
        c3[i] -= (c_0[i] << 1) + c_0[i];
        c3[i] += c_1[i];
        c3[i] += (c_inf[i] << 3) + (c_inf[i] << 2);
        c3[i] /= 6;
    }
    // ==== c2 = 3 * c(-1) - 6 * c(0) + 3 * c(1) - 6 * c(inf) / 6
    for (int i = 0; i < n2; i++)
    {
        c2[i] = (c_m1[i] << 1) + c_m1[i];
        c2[i] -= (c_0[i] << 2) + (c_0[i] << 1);
        c2[i] += (c_1[i] << 1) + c_1[i];
        c2[i] -= (c_inf[i] << 2) + (c_inf[i] << 1);
        c2[i] /= 6;
    }
    // ==== c1 = c(-2) - 6 * c(-1) + 3 * c(0) + 2 * c(1) - 12 * c(inf) / 6
    for (int i = 0; i < n2; i++)
    {
        c1[i] = c_m2[i];
        c1[i] -= (c_m1[i] << 2) + (c_m1[i] << 1);
        c1[i] += (c_0[i] << 1) + c_0[i];
        c1[i] += (c_1[i] << 1);
        c1[i] -= (c_inf[i] << 3) + (c_inf[i] << 2);
        c1[i] /= 6;
    }
    // ==== c0 = 6 * c(0) / 6
    for (int i = 0; i < n2; i++)
    {
        c0[i] = c_0[i];
    }
    // ==== z = c4 * x^4 + c3 * x^3 + c2 * x^2 + c1 * x + c0
    for (int i = 0; i < n2; i++)
    {
        z[i + n4] += c4[i];
        z[i + n3] += c3[i];
        z[i + n2] += c2[i];
        z[i + n1] += c1[i];
        z[i] += c0[i];
    }
}
 


    /// <summary>
    /// 乘积和的进位计算
    /// </summary>
    /// <param name="a"></param>
    /// <param name="n"></param>
    /// <exception cref="Exception"></exception>
    private static void toom_cook3_carry(int[] a, int n)
    {
        int cr = 0;
        for (int i = 0; i < n; i++)
        {
            a[i] += cr;
            if (a[i] < 0)
            {
                cr = -(-(a[i] + 1) / 10 + 1);
            }
            else
            {
                cr = a[i] / 10;
            }
            a[i] -= cr * 10;
        }
        if (cr != 0)
        {
            // Overflow
            throw new Exception("OVERFLOW! cr=" + cr);
        }
    }

2 代码格式

/// <summary>
/// 《小白学程序》第二十六课:大数(BigInteger)的Toom-Cook 3乘法
/// Toom-Cook 3-Way Multiplication
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static string toom_cook3_multiply(string a, string b)
{int n = Math.Max(a.Length, b.Length);int[] ra = string_to_digitals(a, n);int[] rb = string_to_digitals(b, n);toom_cook3_process_00(ra, rb, out int[] rz);toom_cook3_carry(rz, n * 2);return digitals_to_string(rz);
}/// <summary>
/// 短数字的乘法(常规乘法,小学生算法)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="z"></param>
private static void toom_cook3_normal(int[] a, int[] b, ref int[] z)
{int n = a.Length;for (int j = 0; j < n; j++){for (int i = 0; i < n; i++){z[j + i] += a[i] * b[j];}}
}/// <summary>
/// 完全按原始C++代码改写;运行成功;
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="z"></param>
private static void toom_cook3_process_01(int[] a, int[] b, out int[] z)
{int n = a.Length;int n1 = n * 1 / 3;int n2 = n * 2 / 3;int n3 = n * 3 / 3;int n4 = n * 4 / 3;z = new int[n * 2];if (n <= 9){toom_cook3_normal(a, b, ref z);return;}// int *a0 = &a[0];// Multiplicand / right side array pointerint a0 = 0;// int *a1 = &a[tLen / 3];// Multiplicand / central array pointerint a1 = n1;// int *a2 = &a[tLen * 2/ 3];// Multiplicand / left side array pointerint a2 = n2;// n * 2 / 3;// int *b0 = &b[0];// Multiplier / right side array pointerint b0 = 0;// int *b1 = &b[tLen / 3];// Multiplier / central array pointerint b1 = n1;// int *b2 = &b[tLen * 2 / 3];// Multiplier / left side array pointerint b2 = n2;// n * 2 / 3;// int *c0 = &z[(tLen / 3) * 0];int[] c0 = new int[n2];int[] c1 = new int[n2];// int *c2 = &z[(tLen / 3) * 2];int[] c2 = new int[n2];int[] c3 = new int[n2];// int *c4 = &z[(tLen / 3) * 4];int[] c4 = new int[n2];int[] a_m2 = new int[n1];  // a(-2)int[] a_m1 = new int[n1];  // a(-1)int[] a_0 = new int[n1];   // a(0)int[] a_1 = new int[n1];   // a(1)int[] a_inf = new int[n1]; // a(inf)int[] b_m2 = new int[n1];  // b-2)int[] b_m1 = new int[n1];  // b-1)int[] b_0 = new int[n1];   // b(0)int[] b_1 = new int[n1];   // b(1)int[] b_inf = new int[n1]; // b(inf)// ==== a(-2) = 4 * a2 - 2 * a1 + a0, b(-2) = 4 * b2 - 2 * b1 + b0for (int i = 0; i < n1; i++){a_m2[i] = (a[a2 + i] << 2) - (a[a1 + i] << 1) + a[a0 + i];b_m2[i] = (b[b2 + i] << 2) - (b[b1 + i] << 1) + b[b0 + i];}// ==== c(-2) = a(-2) * b(-2)toom_cook3_process_01(a_m2, b_m2, out int[] c_m2);// ==== a(-1) = a2 - a1 + a0, b(-1) = b2 - b1 + b0for (int i = 0; i < n1; i++){a_m1[i] = a[a2 + i] - a[a1 + i] + a[a0 + i];b_m1[i] = b[b2 + i] - b[b1 + i] + b[b0 + i];}// ==== c(-1) = a(-1) * b(-1)toom_cook3_process_01(a_m1, b_m1, out int[] c_m1);// ==== a(0) = a0, b(0) = b0for (int i = 0; i < n1; i++){a_0[i] = a[a0 + i];b_0[i] = b[b0 + i];}// ==== c(0) = a(0) * b(0)toom_cook3_process_01(a_0, b_0, out int[] c_0);// ==== a(1) = a2 + a1 + a0, b(1) = b2 + b1 + b0for (int i = 0; i < n1; i++){a_1[i] = a[a2 + i] + a[a1 + i] + a[a0 + i];b_1[i] = b[b2 + i] + b[b1 + i] + b[b0 + i];}// ==== c(1) = a(1) * b(1)toom_cook3_process_01(a_1, b_1, out int[] c_1);// ==== a(inf) = a2, b(inf) = b2for (int i = 0; i < n1; i++){a_inf[i] = a[a2 + i];b_inf[i] = b[b2 + i];}// ==== c(inf) = a(inf) * b(inf)toom_cook3_process_01(a_inf, b_inf, out int[] c_inf);// ==== c4 = 6 * c(inf) / 6for (int i = 0; i < n2; i++){c4[i] = c_inf[i];}// ==== c3 = -c(-2) + 3 * c(-1) - 3 * c(0) + c(1) + 12 * c(inf) / 6for (int i = 0; i < n2; i++){c3[i] = -c_m2[i];c3[i] += (c_m1[i] << 1) + c_m1[i];c3[i] -= (c_0[i] << 1) + c_0[i];c3[i] += c_1[i];c3[i] += (c_inf[i] << 3) + (c_inf[i] << 2);c3[i] /= 6;}// ==== c2 = 3 * c(-1) - 6 * c(0) + 3 * c(1) - 6 * c(inf) / 6for (int i = 0; i < n2; i++){c2[i] = (c_m1[i] << 1) + c_m1[i];c2[i] -= (c_0[i] << 2) + (c_0[i] << 1);c2[i] += (c_1[i] << 1) + c_1[i];c2[i] -= (c_inf[i] << 2) + (c_inf[i] << 1);c2[i] /= 6;}// ==== c1 = c(-2) - 6 * c(-1) + 3 * c(0) + 2 * c(1) - 12 * c(inf) / 6for (int i = 0; i < n2; i++){c1[i] = c_m2[i];c1[i] -= (c_m1[i] << 2) + (c_m1[i] << 1);c1[i] += (c_0[i] << 1) + c_0[i];c1[i] += (c_1[i] << 1);c1[i] -= (c_inf[i] << 3) + (c_inf[i] << 2);c1[i] /= 6;}// ==== c0 = 6 * c(0) / 6for (int i = 0; i < n2; i++){c0[i] = c_0[i];}// ==== z = c4 * x^4 + c3 * x^3 + c2 * x^2 + c1 * x + c0for (int i = 0; i < n2; i++){z[i + n4] += c4[i];z[i + n3] += c3[i];z[i + n2] += c2[i];z[i + n1] += c1[i];z[i] += c0[i];}
}/// <summary>/// 乘积和的进位计算/// </summary>/// <param name="a"></param>/// <param name="n"></param>/// <exception cref="Exception"></exception>private static void toom_cook3_carry(int[] a, int n){int cr = 0;for (int i = 0; i < n; i++){a[i] += cr;if (a[i] < 0){cr = -(-(a[i] + 1) / 10 + 1);}else{cr = a[i] / 10;}a[i] -= cr * 10;}if (cr != 0){// Overflowthrow new Exception("OVERFLOW! cr=" + cr);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/81654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ansible自动化:简化你的运维任务

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Matlab图像处理-HSI模型

HSI模型 HSI模型是从人的视觉系统出发&#xff0c;直接使用颜色三要素色调(Hue)、饱和度(Saturation)和亮度&#xff08;Intensity&#xff09;来描述颜色。 亮度是指人眼感知光线的明暗程度。光的能量越大&#xff0c;亮度就越大。 色调是颜色最重要的属性。 它决定了颜色的…

GeoServer(配合Tomcat)安装与配置

GeoServer是什么&#xff1f; GeoServer是用于共享地理空间数据的开源服务器。专为互操作性而设计&#xff0c;它使用开放标准发布来自任何主要空间数据源的数据。GeoServer实现了行业标准的OGC协议&#xff0c;例如Web功能服务 (WFS)&#xff0c;Web地图服务 (WMS) 和Web覆盖…

C++之vector迭代器函数begin、end、rebegin、rend、cbegin、cend、crbegin、crend总结(二百零一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

深度学习(Python)学习笔记2

第二章 感知机 2.1 感知机是什么 感知机接收多个输入信号,输出一个信号。 感知机的信号会形成流,向前方输送信息。 感知机的信号只有“流/不流”(1/0)两种取值。 本学习笔记中,0对应“不传递信号”,1对应“传递信号”。 图中、是输入信号,是输出信号,、是权重。图…

小米6/6X/米8/米9手机刷入鸿蒙HarmonyOS.4.0系统-刷机包下载-遥遥领先

小米手机除了解锁root权限&#xff0c;刷GSI和第三方ROM也是米粉的一大爱好&#xff0c;这不&#xff0c;在华为发布了HarmonyOS.4.0系统后不久&#xff0c;我们小米用户也成功将自己的手机干山了HarmonyOS.4.0系统。虽然干上去HarmonyOS.4.0系统目前BUG非常多&#xff0c;根本…

LeetCode刷题笔记【33】:动态规划专题-5(最后一块石头的重量 II、目标和、一和零)

文章目录 前置知识1049. 最后一块石头的重量 II题目描述解题思路代码 494. 目标和题目描述用回溯算法转换为背包问题动态规划 474.一和零题目描述解题思路代码 总结 前置知识 今天是动态规划专题的第5篇, 也是背包问题的第2篇. 所以本文和动态规划专题的1~3弱相关, 和上一篇, …

Prometheus-PushGateway自定义监控项

文章目录 一、前言二、PushGateway安装三、PushGateway的使用四、PushGateway脚本思路 一、前言 pushgateway相比较exporter是主动向服务器发送请求&#xff0c;pushgateway本身也是一个程序&#xff0c;可以运行在任意节点上(不是必须在被监控端)&#xff0c;运行本身没有抓取…

项目:TCP在线云词典

一.要求 1.搭建的框架环境中实现并发&#xff0c;实现多个用户同时查询的功能。 2.服务器分别保存每个用户的使用记录&#xff0c;客户端可以查询日志的功能。 3.基本的查询单词的功能。 4.密码验证的功能&#xff0c;实现登录验证账号和密码是否正确。 二.流程和框架 框架 …

【Python+selenium】生成测试报告

批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。 unittest里面是不能生成html格式报告的&#xff0c;需要导入一个第三方的模块&#xff1a;HTMLTestRunner 一、导入HTMLT…

蓝牙技术|多快好省的苹果Find My查找定位方案商:北京自在科技

在电子市场里&#xff0c;各种蓝牙定位器品牌争奇斗艳&#xff0c;例如国外的Tile Mate 和 Slim&#xff0c;三星的 Galaxy SmartTag 和 Galaxy SmartTag&#xff0c;Chipolo 的ONE Spot&#xff0c;还有苹果的 AirTag 等等。而国内也有着不少优秀的品牌&#xff0c;如Nutale的…

多输入多输出 | MATLAB实现CNN-LSTM-Attention卷积神经网络-长短期记忆网络结合SE注意力机制的多输入多输出预测

多输入多输出 | MATLAB实现CNN-LSTM-Attention卷积神经网络-长短期记忆网络结合SE注意力机制的多输入多输出预测 目录 多输入多输出 | MATLAB实现CNN-LSTM-Attention卷积神经网络-长短期记忆网络结合SE注意力机制的多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预…

python抠图(去水印)开源库lama-cleaner入门应用实践

1. 关于 Lama Cleaner Lama Cleaner 是由 SOTA AI 模型提供支持的免费开源图像修复工具。可以从图片中移除任何不需要的物体、缺陷和人&#xff0c;或者擦除并替换&#xff08;powered by stable diffusion&#xff09;图片上的任何东西。 特征&#xff1a; 完全免费开源&am…

YOLO物体检测-系列教程2:YOLOV2整体解读

&#x1f388;&#x1f388;&#x1f388;YOLO 系列教程 总目录 YOLOV1整体解读 YOLOV2整体解读 YOLOV2提出论文&#xff1a;YOLO9000: Better, Faster, Stronger 1、YOLOV1 优点&#xff1a;快速&#xff0c;简单&#xff01;问题1&#xff1a;每个Cell只预测一个类别&…

ros----发布者和订阅者模型

话题模型&#xff1a; 如何自定义话题消息 1.定义msg文件 2.在package.xml中添加功能包依赖 <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>3.在CMakeList.txt文件中添加编译选项 4.编译生成语言的相…

医院安全不良事件报告系统源码 PHP+ vue2+element+ laravel8+ mysql5.7+ vscode开发

不良事件上报系统通过 “事前的人员知识培训管理和制度落地促进”、“事中的事件上报和跟进处理”、 以及 “事后的原因分析和工作持续优化”&#xff0c;结合预存上百套已正在使用的模板&#xff0c;帮助医院从对护理事件、药品事件、医疗器械事件、医院感染事件、输血事件、意…

JWT安全及案例实战

文章目录 JWT 安全1. Cookie2. Session3. Token4. JWT4.1 JWT概述4.1.1 JWT头4.1.2 有效载荷4.1.3 签名哈希4.1.4 通信流程 4.2 JWT 漏洞描述4.3 JWT 漏洞原理4.4 JWT 安全防御 5. WebGoat 靶场实验5.1 第四关5.2 第五关5.3 第七关 越权与逻辑漏洞 Web漏洞点只有一个入口&#…

12306 抢票小助手: 完整易用的抢票解决方案 | 开源日报 0917

testerSunshine/12306 Stars: 31.4k License: MIT 12306 购票小助手是一个使用 Python 编写的项目&#xff0c;主要功能包括自动打码、自动登录、准点预售和捡漏、智能候补以及邮件通知等。该项目具有以下核心优势&#xff1a; 支持多个版本的 Python提供验证码本地识别功能可…

企业架构LNMP学习笔记46

PHP测试连接代码&#xff1a; php代码测试使用memcached&#xff1a; 示例代码&#xff1a; <?php //实例化类 $mem new memcached(); //调用连接memcached方法 注意连接地址和端口号 $mem->addServer(192.168.17.114,11211); //存数据 var_dump($mem->set(name,l…

AUTOSAR通信篇 - CAN网络通信(五:ComM)

文章目录 模块交互EcuM交互BswM交互NvM交互CanSM交互NM交互 ComM功能Paritial Network Cluster 管理Partial Network Cluster 管理功能ComM PNC状态机在主状态COMM_PNC_NO_COMMUNICATION中PNC的行为PNC网关相关的要求 从断电进入PNC主状态COMM_PNC_NO_COMMUNICATION时在主状态C…