当前位置: 首页 > news >正文

C#,《小白学程序》第二十二课:大数的乘法(BigInteger Multiply)

1 文本格式

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;

/// <summary>
/// 大数的(加减乘除)四则运算、阶乘运算
/// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法
/// </summary>
public static class BigInteger_Utility
{
    /// <summary>
    /// 记录 加减乘除 的运算次数
    /// </summary>
    public static int[] operations { get; set; } = new int[] { 0, 0, 0, 0 };

    /// <summary>
    /// 《小白学程序》第十九课:随机数(Random)第六,随机生成任意长度的大数(BigInteger)
    /// 一般可将超过9位数的数字成为“大数”。
    /// 两个大数之间的四则运算用于密码学、高精度计算等应用。
    /// 位数很多的浮点数可转为大数,再逆转即可。
    /// </summary>
    /// <param name="n"></param>
    /// <returns></returns>
    public static string rand(int n)
    {
        // 随机数发生器
        Random rnd = new Random();
        StringBuilder sb = new StringBuilder();
        // 第一个数字不能为0,故:0-8之间的随机数+ 1 = 1-9
        sb.Append((rnd.Next(9) + 1).ToString());
        // 后面 n-1 个数字为 0-9;从 1 开始计数
        for (int i = 1; i < n; i++)
        {
            sb.Append((rnd.Next(10)).ToString());
        }
        return sb.ToString();
    }

    /// <summary>
    /// 字符串型的数字转为数组
    /// 低位(右)在前,比如 "123" , n=6 存为 3,2,1,_,_,_
    /// n 可能大于 a 的长度;剩余位置留出来用于 进位 等。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="n">最大位数,后面留0</param>
    /// <returns></returns>
    public static int[] string_to_digitals(string a, int n)
    {
        // 字符串 转为 “字符数组”
        char[] c = a.ToCharArray();
        // 存储数字的数组
        int[] d = new int[n];
        // 从最右端(个位)数字开始,转存为数字数组,参与后面的计算
        for (int i = a.Length - 1, j = 0; i >= 0; i--)
        {
            // 跳过数字前面可能有的 - 号
            if (a[i] == '-') continue;
            // '0' 字符是最小的数字字符
            // 数值 = 字符 - '0' ;
            d[j++] = a[i] - '0';
        }
        return d;
    }

    /// <summary>
    /// 数组型数字转为字符串型
    /// 低位(右)在前,比如 3,2,1,_,_,_ 转为 "123", n=6
    /// 这是前面 string_to_digitals 的反向计算函数
    /// n 可能大于 d 的长度;剩余位置留出来用于 进位 等。
    /// </summary>
    /// <param name="d"></param>
    /// <returns></returns>
    public static string digitals_to_string(int[] d)
    {
        int n = d.Length;
        // 数字数组 d 含有一些无效的数组;
        // 因此,先从最右段开始去除无效的位置
        int k = n - 1;
        //for (; (k >= 0) && (d[k] == 0); k--) ;
        while ((k >= 0) && (d[k] == 0)) k--;
        // 找到有效位置后,开始组合字符串;
        if (k >= 0)
        {
            StringBuilder sb = new StringBuilder();
            for (; k >= 0; k--) sb.Append(d[k]);
            return sb.ToString();
        }
        else
        {
            return "0";
        }
    }

  

    /// <summary>
    /// 《小白学程序》第二十二课:大数(BigInteger)的四则运算之三,乘法
    /// 大数乘法 c = a * b
    /// 本算法与小学生算法基本一致,主要的区别是:
    ///     小学生算法每两个位数的数字相乘后立即进位;
    ///     而本程序则是先计算全部相乘,最后统一进位。
    /// 可能出乎大家的意料!虽然很多大牛发明了多种算法,
    /// 如果进行编译器自动优化,该算法居然经常是最快的。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_multiply(string a, string b)
    {
        int na = a.Length;
        int nb = b.Length;
        int n = na + nb + 1;
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        // 乘数的每一位 乘以 被乘数
        int[] dc = new int[n];
        for (int i = 0; i < na; i++)
        {
            for (int j = 0; j < nb; j++)
            {
                dc[i + j] += da[i] * db[j];
            }
        }
        // 所有位置进位
        for (int i = 0; i < n; i++)
        {
            if (dc[i] >= 10)
            {
                dc[i + 1] += (dc[i] / 10);
                dc[i] %= 10;
            }
        }

        return digitals_to_string(dc);
    }
}

2 代码格式

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;/// <summary>
/// 大数的(加减乘除)四则运算、阶乘运算
/// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法
/// </summary>
public static class BigInteger_Utility
{/// <summary>/// 记录 加减乘除 的运算次数/// </summary>public static int[] operations { get; set; } = new int[] { 0, 0, 0, 0 };/// <summary>/// 《小白学程序》第十九课:随机数(Random)第六,随机生成任意长度的大数(BigInteger)/// 一般可将超过9位数的数字成为“大数”。/// 两个大数之间的四则运算用于密码学、高精度计算等应用。/// 位数很多的浮点数可转为大数,再逆转即可。/// </summary>/// <param name="n"></param>/// <returns></returns>public static string rand(int n){// 随机数发生器Random rnd = new Random();StringBuilder sb = new StringBuilder();// 第一个数字不能为0,故:0-8之间的随机数+ 1 = 1-9sb.Append((rnd.Next(9) + 1).ToString());// 后面 n-1 个数字为 0-9;从 1 开始计数for (int i = 1; i < n; i++){sb.Append((rnd.Next(10)).ToString());}return sb.ToString();}/// <summary>/// 字符串型的数字转为数组/// 低位(右)在前,比如 "123" , n=6 存为 3,2,1,_,_,_/// n 可能大于 a 的长度;剩余位置留出来用于 进位 等。/// </summary>/// <param name="a"></param>/// <param name="n">最大位数,后面留0</param>/// <returns></returns>public static int[] string_to_digitals(string a, int n){// 字符串 转为 “字符数组”char[] c = a.ToCharArray();// 存储数字的数组int[] d = new int[n];// 从最右端(个位)数字开始,转存为数字数组,参与后面的计算for (int i = a.Length - 1, j = 0; i >= 0; i--){// 跳过数字前面可能有的 - 号if (a[i] == '-') continue;// '0' 字符是最小的数字字符// 数值 = 字符 - '0' ;d[j++] = a[i] - '0';}return d;}/// <summary>/// 数组型数字转为字符串型/// 低位(右)在前,比如 3,2,1,_,_,_ 转为 "123", n=6/// 这是前面 string_to_digitals 的反向计算函数/// n 可能大于 d 的长度;剩余位置留出来用于 进位 等。/// </summary>/// <param name="d"></param>/// <returns></returns>public static string digitals_to_string(int[] d){int n = d.Length;// 数字数组 d 含有一些无效的数组;// 因此,先从最右段开始去除无效的位置int k = n - 1;//for (; (k >= 0) && (d[k] == 0); k--) ;while ((k >= 0) && (d[k] == 0)) k--;// 找到有效位置后,开始组合字符串;if (k >= 0){StringBuilder sb = new StringBuilder();for (; k >= 0; k--) sb.Append(d[k]);return sb.ToString();}else{return "0";}}/// <summary>/// 《小白学程序》第二十二课:大数(BigInteger)的四则运算之三,乘法/// 大数乘法 c = a * b/// 本算法与小学生算法基本一致,主要的区别是:///     小学生算法每两个位数的数字相乘后立即进位;///     而本程序则是先计算全部相乘,最后统一进位。/// 可能出乎大家的意料!虽然很多大牛发明了多种算法,/// 如果进行编译器自动优化,该算法居然经常是最快的。/// </summary>/// <param name="a"></param>/// <param name="b"></param>/// <returns></returns>public static string big_integer_multiply(string a, string b){int na = a.Length;int nb = b.Length;int n = na + nb + 1;int[] da = string_to_digitals(a, n);int[] db = string_to_digitals(b, n);// 乘数的每一位 乘以 被乘数int[] dc = new int[n];for (int i = 0; i < na; i++){for (int j = 0; j < nb; j++){dc[i + j] += da[i] * db[j];}}// 所有位置进位for (int i = 0; i < n; i++){if (dc[i] >= 10){dc[i + 1] += (dc[i] / 10);dc[i] %= 10;}}return digitals_to_string(dc);}
}

3 计算结果

http://www.lryc.cn/news/245844.html

相关文章:

  • kafka,RabbitMQ,RocketMQ,他们之间的区别,架构,如何保证消息的不丢失,保证不重复消费,保证消息的有序性
  • uni-app中vue3+setup实现下拉刷新、上拉加载更多效果
  • 微服务实战系列之Nginx(技巧篇)
  • 好工具|datamap,一个好用的地图可视化Excel插件,在Excel中实现地理编码、拾取坐标
  • Java——继承
  • 十、sdl显示yuv图片
  • Docker Nginx容器部署vue项目
  • 【深度学习】如何找到最优学习率
  • 详解—C++三大特性——多态
  • 用idea搭建一个spring cloud微服务项目
  • SpringBoot——启动类的原理
  • Rust语言入门教程(七) - 所有权系统
  • 【MATLAB源码-第89期】基于matlab的灰狼优化算法(GWO)无人机三维路径规划,输出做短路径图和适应度曲线
  • 线程池的饱和策略有哪些?
  • Git设置多个仓库同时推送
  • 前端入职环境安装
  • 《金融科技行业2023年专利分析白皮书》发布——科技变革金融,专利助力行业发展
  • Introducing the Arm architecture
  • Python 使用SQLAlchemy数据库模块
  • 【nlp】4.3 nlp中常用的预训练模型(BERT及其变体)
  • IDEA中 java: 警告: 源发行版 11 需要目标发行版 11 如何解决
  • APP测试的测试内容有哪些,常见的Bug分类介绍!
  • 【Java程序员面试专栏 专业技能篇】Java SE核心面试指引(三):核心机制策略
  • 网络运维与网络安全 学习笔记2023.11.22
  • Android虚拟化
  • Nginx如何配置负载均衡
  • Python虚拟环境
  • 单片机学习4——中断的概念
  • Go语言网络爬虫工程经验分享:pholcus库演示抓取头条新闻的实例
  • Git安装