蓝桥杯 阶乘计算 高精度加法(Java)

1.题目描述

输入一个正整数n,输出n!的值。
其中n!=123*…*n。
算法描述
n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。
使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
输入 输入包含一个正整数n,n< = 1000。
输出 输出n!的准确值。
样例输入 10
样例输出 3628800

2.思路

刚开始自己写了很多乱七八糟的方法,还写不出来,还有主要没理解透进位写法的妙处。然后在网上搜了一下,发现普遍都是下面这种方法,自己看了下,然后写了一遍。由于很久之前卡在这题,然后就过年没看了,参考文章也不知道具体是哪篇了,就不放链接了。记录一下代码

import java.util.Scanner;
public class FactorialCalculation {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		factorial(n);
	}
	public static void factorial(int n) {
    
    
		int temp;//存储临时结果
		int jinwei = 0;//进制
		int[] a = new int[9999];
		a[0] = 1;//代表个位
		for(int i = 2; i <= n; ++i) {
    
    //第一层循环是从1到n,表示阶乘的每一项,因为已经让a[0]等于1了,从2开始即可
			for(int j = 0; j < a.length; ++j) {
    
    //第二层循环是计算阶乘的结果,因为不知道进位的情况,所以不能判断计算结果会存储到哪一位,就只能让0累加到9998
				temp = a[j] * i + jinwei;//必须要加上jinwei,非常巧妙
				a[j] = temp % 10;
				jinwei = temp / 10;
				
			}
		}
//		将数组倒序输出即得到结果
		int notZeroStart = 0;
		for(int i = a.length - 1; i >= 0 ; --i) {
    
    
			if(a[i] != 0) {
    
    //遇到第一个不为0的时候就要开始全部输出
				notZeroStart = i ;//记录非零位置
				break;//别忘了break;
			}
		}
	for(int i = notZeroStart; i >= 0; --i) {
    
    
		System.out.print(a[i]);
	}
}
}

然后经过这道题的熏陶,又刷到了一道类似题,在我深刻参悟刚才那道题之后,然后做起来就轻松了

3.题目描述

输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
算法描述
由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.
如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。最后将C输出即可。
输入
输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出
输出一行,表示a + b的值。
样例输入
20100122201001221234567890
2010012220100122
样例输出
20100122203011233454668012

4.代码

import java.util.Scanner;
public class HighPrecisionAddition {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		//a和b都不超过100位。此时已经不能用int存储了
		String a = sc.next();
		String b = sc.next();
		add(a,b);
	}

	private static void add(String a, String b) {
    
    
		//定义三个数组
		int[] A = new int[100];
		int[] B = new int[100];
		int[] C = new int[9999];
		//先将a,b用数组储存起来
		int j = 0;//为了个位在A[0]处存储
		for(int i = a.length() - 1; i >= 0; --i) {
    
    
			A[j] = Integer.valueOf(a.substring(i, i+1)).intValue();
			j += 1;
		}
		j = 0;
		for(int i = b.length() - 1; i >= 0; --i) {
    
    
			B[j] = Integer.valueOf(b.substring(i, i+1)).intValue();
			j += 1;
		}//存储结束
		int tempRes;//存储临时结果
		int jinwei = 0;//保存进位
		int lengthBigger = 0;//记录A,B数组中更长的一组的长度
		if(A.length > B.length) {
    
    
			lengthBigger = A.length;
		} else {
    
    
			lengthBigger = B.length;
		}
		//开始进行计算
		for(int m = 0; m < lengthBigger; ++m) {
    
    
			tempRes = A[m] + B[m] + jinwei;
			C[m] = tempRes % 10;
			jinwei = tempRes / 10;
		}
		//最后逆序输出得到答案
		int notZeroIndex = 0;//先找到非零位
		for(int i = C.length - 1; i >= 0; --i) {
    
    
			if(C[i] != 0) {
    
    
				notZeroIndex = i;
				break;
			}
		}
		for(int i = notZeroIndex; i >= 0; --i) {
    
    
			System.out.print(C[i]);
		}	
	}
}

5.参考文章

复制一个方法:int与String之间的互相转换,老是忘记:
来源:link.
1 如何将字串 String 转换成整数 int?
A. 有两个方法:
1、 int i = Integer.parseInt([String]); 或 i = Integer.parseInt([String],[int radix]);
2、 int i = Integer.valueOf(my_str).intValue();
注: 字串转成 Double, Float, Long 的方法大同小异.

2 如何将整数 int 转换成字串 String ?
A. 有叁种方法:

1、String s = String.valueOf(i);
2、String s = Integer.toString(i);
3、String s = “” + i;
注: Double, Float, Long 转成字串的方法大同小异.

int -> String
int i=12345;

String s="";

第一种方法:s=i+"";

第二种方法:s=String.valueOf(i);

这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢?

String -> int
s=“12345”;

int i;

第一种方法:i=Integer.parseInt(s);

第二种方法:i=Integer.valueOf(s).intValue();

这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢?

以下是答案:

第一种方法:s=i+""; //会产生两个String对象

第二种方法:s=String.valueOf(i); //直接使用String类的静态方法,只产生一个对象

第一种方法:i=Integer.parseInt(s); //直接使用静态方法,不会产生多余的对象,但会抛出异常

第二种方法:i=Integer.valueOf(s).intValue(); //Integer.valueOf(s) 相当于 new Integer(Integer.parseInt(s)),也会抛异常,但会多产生一个对象

6.学习心得:多积累,高精度加法肯定不是最好的算法,但这是自己动脑壳写出来的题。

猜你喜欢

转载自blog.csdn.net/balder_girl/article/details/113817863