import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); while(in.hasNextInt()){ BigInteger t=new BigInteger("1"); int n=in.nextInt(); for(int i=1;i<=n;i++){ BigInteger c=new BigInteger(String.valueOf(i)); t=t.multiply(c); } System.out.println(t); } in.close(); }} 这道题求阶乘,以为象前面做的那道一样简单,所以没有细想,提交了好多次,有个测试按例通不过, 后来发现是698阶乘的时候,我自己定义的long已经存不下了,这时候自然而然的想到了大数字处理类。
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void Add(){ Scanner input = new Scanner(System.in); BigInteger a = input.nextBigInteger(); BigInteger b = input.nextBigInteger(); System.out.println(a.add(b)); } public static void Factorial(){ Scanner input = new Scanner(System.in); int n = input.nextInt(); //求n的阶乘 BigInteger answer = new BigInteger("1"); //结果初值为1 for(int i = 1; i<=n; i++){ //answer不能直接与i相乘 //大整数只能与大整数相乘 //调用valueOf方法把int型的i赋值给一个大整形数,然后再相乘 BigInteger current = BigInteger.valueOf(i); answer = answer.multiply(current); } System.out.println(answer); } public static void main(String[] args) { Factorial(); } }
/* *直接上高精度阶乘。 */ #include<bits/stdc++.h> using namespace std; vector<int> v; void multi(int x) //先各个位乘 再处理进位 { for(int i = 0;i < v.size(); i++) v[i] = v[i] * x; } void Jin() //处理进位 { int c = 0; for(int i = 0;i < v.size(); i++) { int t = v[i]; v[i] = (t+c)%10; c = (t+c)/10; } if(c) v.push_back(c); while(v[v.size()-1] >= 10) //一定要注意 这里最高位可能还>=10 要继续向前进 { int t = v[v.size()-1]; v[v.size()-1] = t%10; v.push_back(t/10); } } int main() { int n; while(cin >> n) //实现n! { v.clear(); v.push_back(1); for(int i = 2;i <= n; i++) { multi(i); Jin(); } for(int i = v.size()-1;i >= 0; i--) cout<<v[i]; cout << '\n'; } return 0; }
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()){ int n = scanner.nextInt(); BigInteger i = new BigInteger("1"); for (int j = 1; j <= n; j++) i=i.multiply(new BigInteger(String.valueOf(j))); System.out.println(i); } } }
#include "stdio.h" #define N 10000 int main(){ int res[1000]; //可以理解为res[1000]数组的每一个元素都记录N进制的1位 //其中N为10的乘方,这样,输出结果刚好可以用十进制表示 //由于N是10的乘方,该N进制的符号是十进制符号的组合,让我想到了等长码了都 //就好像时是16进制可以用4个二进制位表示一样, //要注意保证res数组中所有元素都是4位,出了最高位的前缀0要去除 //越想越远了 int n,i,j,bit,carry;//bit表示当前运算结果的最高位,也就是res数组的不为0的最大下标 //carry表示进位的结果 while(~scanf("%d",&n)){ res[bit=0] = 1;//一开始res数组应该表示1,阶乘,初始值存1, //加法初始值存0,其中只需要初始化数组的第一个元素就行了 for(i = 1; i <= n; i++){ carry = 0; for(j = 0; j <= bit; j++){ res[j] = res[j]*i + carry;//每一位的结果是当前位乘以乘数在加上进位的结果 //第一位运算时进位为0,需要将carry提前初始化为0 carry = res[j] / N;//将当前位的运算结果分解为当前位和高一位存入当前位和carry res[j] = res[j] % N; } //依次从当前位到最高位计算,最高位可能产生进位 if(carry) res[++bit] = carry; } //高位补0用的格式字符串%04d,我看大佬都是用%4.4ld, //不知道为毛,网上也没查出一个好的解释来 for(printf("%d",res[bit]);bit;printf("%04d",res[--bit])); printf("\n"); } return 0; }
//大数乘法 #include<stdio.h> #define MaxSize 1000 const int MOD = 10000; typedef struct { int data[MaxSize]; int len; }BigInt; BigInt multiply(BigInt x, int y) { int i, g = 0, z; for(i = 0; i < x.len; i++) { z = x.data[i] * y + g; x.data[i] = z % MOD; g = z / MOD; } while(g) { x.data[i++] = g % MOD; g /= MOD; } x.len = i; return x; } int main(void) { int n, i; BigInt r; while(~scanf("%d", &n)) { r.data[0] = 1; r.len = 1; for(i = 1; i <= n; i++) r = multiply(r, i); printf("%d", r.data[r.len - 1]); for(i = r.len - 2; i >= 0; i--) printf("%04d", r.data[i]); printf("\n"); } return 0; }
#include<stdio.h> int s[1000]={1},n=1000000,t=2,a=0,b=0,m=0,p; int main() { int N; while(~scanf("%d",&N)) { for(;a<=m||++t<=N&&(a=b=0,1);m==a++&&b&&m++) s[a]=(b+=s[a]*t)%n,b/=n; for(printf("%d",s[p=m]);m--;printf("%06d",s[m])); for(printf("\n");p;s[p--]=0); s[0]=1,a=b=m=0,t=2; } }
#include<stdio.h> #include<string.h> struct bigInteger{ int digit[1000]; //按四位一个单位来保存数值 int size;//下一个我们未使用的数组单元 void init(){ for(int i=0;i<1000;i++) digit[i]=0; size=0; } void set(int x){ init(); do{ digit[size++]=x%10000; x/=10000; }while(x!=0); } void output(){ for(int i=size-1;i>=0;i--){ if(i!=size-1) printf("%04d",digit[i]); else printf("%d",digit[i]); } printf("\n"); } bigInteger operator * (int x) const{ //高精度整数与普通整数的乘积 bigInteger ret; ret.init(); int carry=0; for(int i=0;i<size;i++){ int tmp=x*digit[i]+carry; carry=tmp/10000; tmp%=10000; ret.digit[ret.size++]=tmp; } if(carry!=0){ ret.digit[ret.size++]=carry; } return ret; } }a; int main(){ int n; while(scanf("%d",&n)!=EOF){ a.init(); a.set(1); for(int i=1;i<=n;i++){ a=a*i; } a.output(); } return 0; }
#include <iostream> #include <string.h> using namespace std; int main(){ int N; int s[10000]={0},i;//用于保存超过int范围的超大数字,按照从个位往上进位的方式更新数据 //核心思路:乘法转换成加法 //怎么确定完整数字的终点:最高位数字与i的乘积+前一位进位是否产生进位 while(cin>>N){ memset(s,-1,sizeof(s));// s[0]=1;//将个位设为1 int i,j,temp,k,index;//k记录进位 for(i=1;i<=N;++i){//本轮阶乘的数字 k=0;//进位设置为零 //遍历结果数组中的每个个位整数 for(j=0;s[j]!=-1;++j){//-1标识最高位结束 temp=s[j]*i+k; s[j]=temp%10; k=temp/10;//下一个数的进位 } //***********确定完整数字的终点,或者总共数组长度的方法: //当i乘以当前数组的最高位时,若存在进位则根据当前数组长度递增 while(k){ s[j]=k%10; ++j; k/=10; } index=j-1; } //逆序输出数组中的数字 for(i=index;i>=0;--i) cout<<s[i]; cout<<endl; } }
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); while(in.hasNextInt()){ int N = in.nextInt(); BigInteger sum = BigInteger.valueOf(1); for(int i=1;i<=N;i++) sum = sum.multiply(BigInteger.valueOf(i)); System.out.println(sum); } } }
java也有春天
package com.speical.improve;
import java.util.Scanner;
/**
* 大数的阶乘
* @author special
* @date 2017年12月23日 下午4:36:47
*/
public class Pro23Improve1 {
private static String[] factories = new String[1000 + 5];
static{
factories[0] = "1";
factories[1] = "1";
}
/**
* 两字符串相乘
* @param str1
* @param str2
* @return
*/
public static String mutiple(String str1, String str2){
int length1 = str1.length();
int length2 = str2.length();
int totalLength = length1 + length2;
char[] result = new char[totalLength]; //两数相乘最大位数为 两数位数之和
for(int i = 0; i < totalLength; i++) result[i] = '0'; //注意初始化为'0'
int carry = 0;
for(int j = length2 - 1; j >= 0; j--){
carry = 0;
for(int i = length1 - 1; i >= 0; i--){
int temp = (str1.charAt(i) - '0') * (str2.charAt(j) - '0')
+ (result[i + j + 1] - '0') + carry;
if(temp >= 10){
carry = temp / 10; //注意此处的顺序,坑死我了
temp %= 10;
}else {
carry = 0;
}
result[i + j + 1] = (char) (temp + '0'); // i + j + 1正好第j轮相乘,个位应该放的位置
}
if(carry > 0) result[j] = (char) (carry + '0'); // j 正好是第j轮相乘的应该进位的位置
}
return new String(result).substring(result[0] != '0' ? 0 : 1);
}
public static String getFactories(int n){
String res = "1";
for(int i = n; i >= 2; i--){
if(factories[i] != null){
res = mutiple(res,factories[i]);
break;
}
else
res = mutiple(res, String.valueOf(i));
}
factories[n] = res;
return res;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n = input.nextInt();
System.out.println(getFactories(n));
}
}
}
import java.math.BigInteger; import java.util.Scanner; public class Seven { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()){ int number = sc.nextInt(); System.out.println(jieCheng(number)); } } public static BigInteger jieCheng(int number){ if (number==1){ return BigInteger.valueOf(1); }else return jieCheng(number-1).multiply(BigInteger.valueOf(number)); } }
#include<bits/stdc++.h> int main(){ int n; while(scanf("%d",&n)!=EOF){ long long a[301]={1}; for(int i=2;i<=n;i++){ long long s=0,t; for(int j=0;j<=300;j++){ t=a[j]*i+s;a[j]=t%1000000000; s=t/1000000000; } }//每个数组单元存放9位十进制数字,中间数组单元0的个数会被压缩 int i; for(i=300;a[i]==0;i--); printf("%lld",a[i]); for(int j=i-1;j>=0;j--) printf("%09lld",a[j]);//对中间数组单元的0解压缩 printf("\n"); } }
#include<stdio.h> #define width 3000 int main() { int i,j; int k,r,t; int N; int d[width]; while(scanf("%d",&N)!=EOF) { t=0; for(i=0;i<width;i++) /**给数组初始化为零*/ d[i]=0; d[0]=1; /**个位初始化为1*/ for(i=1;i<=N;i++) /**从1到N进行阶乘*/ { k=0; for(j=0;j<=t;j++)/**从个位开始往高位运算*/ { r=(d[j]*i+k)/10; /**第j位乘以i加上后一位运算得到的k,在除以10得到k*/ d[j]=(d[j]*i+k)%10;/**第j位乘以i加上后一位运算得到的k,再取余得到运算后第j位的只*/ k=r; } while(k!=0) /**k!=0说明要向高位进位*/ { d[++t]=k%10; k=k/10; } } for(i=t;i>=0;i--) /**从个位开始输出各位数字*/ printf("%d",d[i]); printf("\n"); } return 0; }
#include <stdio.h> long res[10000]; int factorial(const int n){ int i,j,carry,bit; for(res[bit=carry=0]=i=1;i<=n;++i,carry=0){ for(j=0;j<=bit;++j){ res[j]=res[j]*i+carry; carry=res[j]/10000; res[j]%=10000; } if (carry) res[++bit]=carry; } for(printf("%ld",res[i=bit]);i;printf("%4.4ld",res[--i])); return printf("\n"); } int main(){ for(int n;~scanf("%d",&n);factorial(n)); return 0; }
#include <iostream>
#define width 3000 //利用数组存储大数,1000!大约是两千多位,使用3000位够了
using namespace std;
int main()
{
int N,i,num[width]={0}; //初始化
while(cin >> N)
{
num[0]=1; //个位为1
int nowWid=1,j,carry,tmp; //nowWid代表当前大数数组位数
for(i=2;i<=N;i++) //从2开始
{
carry=0; //进位初始化为0
for(j=0;j<nowWid;j++)
{
tmp=(num[j]*i+carry)/10; //tmp暂时存储进位值
num[j]=(num[j]*i+carry)%10;
carry=tmp;
}
while(carry != 0) //进位
{
num[nowWid++]=carry%10;
carry /= 10;
}
}
while(nowWid--)
cout << num[nowWid];
cout << endl;
}
return 0;
}
老方法,转化为字符串 #include <bits/stdc++.h> using namespace std; string Multiple(string str,int n) { long long carry=0; for(int i=str.size()-1;i>=0;i--) { long long current=carry+(str[i]-'0')*n; str[i]=current%10+'0'; carry=current/10; } if(carry!=0) { str=to_string(carry)+str; } return str; } int main() { int n; while(cin>>n) { string answer="1"; for(int i=1;i<=n;i++) { answer=Multiple(answer,i); } cout<<answer<<endl; } return 0; }