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

本文主要是介绍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 计算结果

这篇关于C#,《小白学程序》第二十二课:大数的乘法(BigInteger Multiply)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/429507

相关文章

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图