大整数的操作—阶乘,加法,乘法-----比对C++与java

昨天晚上,到今天早上一直在想关于大整数操作,终于有收获了

在这里插入图片描述

大整数的操作—阶乘,加法,乘法-----比对C++与java

我个人觉得c++里面的模板库挺适合刷题的(acm);但是有一个缺点里面不能存放很大的数;但是java可以,虽然我现在还没有正式学过java,只是以前学过一点点,但是这已经足够我去学习java的大数操作。我是一个初学者,如有错误请指教。

  • 先来看一个题目

    1441: N!

    时间限制: 5 Sec 内存限制: 262 MB

    提交: 9 解决: 7

    题目描述

    Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!

    输入

    One N in one line, process to the end of file.

    输出

    For each N, output N! in one line.

    样例输入 [Copy](javascript:CopyToClipboard($(’#sampleinput’).text()))

    1
    2
    3
    

    样例输出 [Copy](javascript:CopyToClipboard($(’#sampleoutput’).text()))

    1
    2
    6
    
  • 这道题可以用C++来写

    思路很简单,就是利用乘法运算中的竖式运算

    这个题暴力是肯定不行,算到20多就炸了,这个题给的范围到10000
    所以,这个题运用到大数运算

    我们用数组a来存储数据的每一位,用digit来表示当前的位数。 并初始化digit=1,a[0]=1;
    n=2 a[0]=2
    n=3 a[0]=6
    n=4 a[0]=4 a[1]=2
    n=5 a[0]=0 a[1]=2 a[2]=1

    看到以上的数据肯定能明白 关键是怎么实现的呢
    存储的数据是从个位开始存储的,只需要temp=a[0]*i+up (i的取值范围 1-n,up模拟的是的一个进位运算,例如n=5的时候 a[0]=(4 * 5)%10=0, 个位确定为0,a[1]=(2 * 5+(20/10))%10=2,十位确定为2 这个时候n=4的时候p=2,已经计算完了,这个时候up=12/10=1!=0 还需要再一次往前进位 a[p]=%10=1 p++ 位数为3 结束)

    这里插入一个视频:

【算法教程】大数加法与大数阶乘

  • AC代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int Maxn=10e5;
    int a[Maxn];  // 用数组a来存储每一位
    int main()
    {
        int n;
        while(cin>>n)
        {
            memset(a,0,sizeof(a));  // 先初始化为0;
            a[0]=1;  // 先将a[0]赋值为1;
            int p=1;  // p代表数组a[p]还未开始储存数字
            for(int i=2;i<=n;i++)  // 模拟n的阶乘
            {
                int up=0,temp=0;  // temp临时储存a[j]*i的值,up代表进位值
                for (int j=0;j<p;j++) // 将 a[j]与i相乘,此处为一个遍历;
                {
                    temp=a[j]*i+up; 
                    up=temp/10;
                    a[j]=temp%10;
                }
                while(up>0)  // 如果up>0;说明往a[p]里面存值了
                {
                    a[p++]=up%10;
                    up/=10;
                }
            }
            for(int i=p-1;i>=0;i--) // 数组的逆序输出;
                cout<<a[i];
            cout<<endl;
        }
        return 0;
    }
    
  • 下面是java的操作:

  • AC源码:(ps:这是一段比较简单的代码就不多注释了)

    package javaLearn;
    import java.util.*;
    import java.math.*;
    public class bigInter {
    	public static void main(String[] args) {
    		Scanner cin=new Scanner(System.in);
    		while (cin.hasNext())
    		{
    			int n=cin.nextInt();
    			BigInteger sum=new BigInteger("1");
    			BigInteger flag=new BigInteger("1");
    			for(int i=0;i<n;i++)
    			{
    				sum=sum.multiply(flag);
    				flag=flag.add(new BigInteger("1"));
    			}
    			System.out.println(sum);
    		}
    	}
    }
    

    下面着重解释一下:

    java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,至于两个类的对象能表示最大范围不清楚,理论上能够表示无线大的数,只要计算机内存足够大。这两个类都在java.math.*包中,因此每次必须在开头处引用该包。

    Ⅰ基本函数:

    1.valueOf(parament); 将参数转换为制定的类型

    比如 int a=3;

    BigInteger b=BigInteger.valueOf(a);

    则b=3;

    String s=”12345”;

    BigInteger c=BigInteger.valueOf(s);

    则c=12345;

    2.add(); 大整数相加

    BigInteger a=new BigInteger(“23”);

    BigInteger b=new BigInteger(“34”);

    a.add(b);

    3.subtract(); 相减

    4.multiply(); 相乘

    5.divide(); 相除取整

    6.remainder(); 取余

    7.pow(); a.pow(b)=a^b

BigInteger

​ 如果在操作的时候一个整型数据已经超过了整数的最大类型长度long的话,则此数据就无法装入,所以,此时要使用BigInteger类进行操作。

img

​ BigInteger是在java.math包中。

  • 样例代码:

    //实例化一个大数字
            BigInteger num1 = new BigInteger("4"); 
            //将普通的数值转换为大数值
            BigInteger num2 = BigInteger.valueOf(3);  
            //取该大数字加2的操作
            System.out.println("加法操作:"+ num1.add(num2)); 
            //取该大数字减2的操作
            System.out.println("减法操作:"+ num1.subtract(num2)); 
            //取该大数字乘以2的操作
            System.out.println("乘法操作:"+ num1.multiply(num2));
            //取该大数字除以2的操作
            System.out.println("除法操作:"+ num1.divide(num2)); 
            //求余
            System.out.println("取余:"+ num1.remainder(num2));
            System.out.println("取余:"+ num1.mod(num2));  
            //取该大数字的2次方
            System.out.println("做2次方操作:"+ num1.pow(2));     
            //取该大数字的相反数
            System.out.println("取相反数操作:"+ num1.negate());
            //取最大公约数
            System.out.println("取最大公约数:"+ num1.gcd(num2)); 
            //取绝对值
            System.out.println("取绝对值:"+ num1.abs()); 
            //判断相等
            System.out.println("判断相等:"+ num1.equals(num2)); 
            //比较大小
            System.out.println("比较大小:"+ num1.compareTo(num2));
            //取较大值
            System.out.println("取较大值:"+ num1.max(num2));
    

BigDecimal

​ 使用此类可以完成大的小数操作,而且也可以使用此类进行精确的四舍五入,这一点在开发中经常使用。
​ 对于不需要任何准确计算精度的程序可以直接使用float或double完成,但是如果需要精确计算结果,则必须使用BigDecimal类。

img

  • 用法示例:

    //实例化一个大数字
            BigDecimal num1 = new BigDecimal("4.10");      
            //将普通的数值转换为大数值
            BigDecimal num2 = BigDecimal.valueOf(3.9); 
            //取该大数字加操作
            System.out.println("加法操作:"+ num1.add(num2));  
            //取该大数字减操作
            System.out.println("减法操作:"+ num1.subtract(num2));  
            //取该大数字乘操作
            System.out.println("乘法操作:"+ num1.multiply(num2)); 
            //取该大数字除操作
            System.out.println("除法操作:"+ num1.divide(num2, 4, RoundingMode.HALF_UP));
            //取该大数字的相反数
            System.out.println("取相反数操作:"+ num1.negate());
            //取绝对值
            System.out.println("取绝对值:"+ num1.abs()); 
            //判断相等, 当且仅当两个BigDecimal对象数值和精度scale均相等时才返回true
            System.out.println("判断相等:"+ num1.equals(BigDecimal.valueOf(41, 1)));
            System.out.println("判断相等:"+ num1.equals(BigDecimal.valueOf(410, 2)));
            //比较大小,仅比较两个BigDecimal对象数值是否相等,忽略精度
            System.out.println("比较大小:"+ num1.compareTo(BigDecimal.valueOf(41, 1)));
            System.out.println("比较大小:"+ num1.compareTo(BigDecimal.valueOf(410, 2))); 
            //取较大值
            System.out.println("取较大值:"+ num1.max(num2));
    

我以大整数为例,用代码示例一次:

package javaLearn;
import java.util.*;
import java.math.*;
public class bigInter {
	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		while (cin.hasNext())
		{
			BigInteger sum=cin.nextBigInteger();
			BigInteger flag=cin.nextBigInteger();
			System.out.println("乘法操作:"+sum.add(flag));
			System.out.println("减法操作:"+ sum.subtract(flag)); 
			System.out.println("乘法操作:"+ sum.multiply(flag));
		    System.out.println("除法操作:"+ sum.divide(flag)); 
         System.out.println("取余:"+ sum.remainder(flag));
		    System.out.println("取最大公约数:"+ sum.gcd(flag)); 
		}
	}
}

// 输出示例:
78 9
乘法操作:87
减法操作:69
乘法操作:702
除法操作:8
取余:6
取最大公约数:3

  • 有了java神器,再看一道题

    大整数乘法

    时间限制: 1 Sec 内存限制: 128 MB

    提交: 393 解决: 181

    题目描述

    使用分治算法实现两个大整数相乘。

    输入

    两个十进制大整数,满足每一个整数长度为2^n且两个大整数的长度相等。(多组数据)

    输出

    两个大整数的乘积。

    样例输入 [Copy](javascript:CopyToClipboard($(’#sampleinput’).text()))

    1234 5678
    

    样例输出 [Copy](javascript:CopyToClipboard($(’#sampleoutput’).text()))

    7006652
    
  • 有了java这波神操作,是不是很简单,没错哦!就是这么简单

  • AC代码:

    import java.math.BigDecimal;
    import java.util.Scanner;
    public class Main {
        public static void main(String[] args) {
            Scanner cin=new Scanner(System.in);
            BigDecimal A,B;
            while(cin.hasNext()){
                 A=cin.nextBigDecimal();
                 B=cin.nextBigDecimal();
                System.out.println(A.multiply(B));          
            }
        }
      
    }
    

好了,今天这波就介绍到这里了。

喜欢的话,就点个赞吧!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章