初版(当数值大时,不可用!)
程序中使用递归的方式计算阶乘,每次调用fact()函数时,会将n减1,并将n与递归返回值相乘。当n较大时,这种递归方式会导致栈空间占用过多,从而引发栈溢出的错误。
#include<stdio.h>
long long fact(int n){
if(n==1 || n==0) return 1;
return (long long)n * fact(n-1);
}
int main()
{
int n;
scanf("%d", &n);
printf("%lld",fact(n));
return 0;
}
进阶版
程序中使用递归的方式计算阶乘,每次调用fact()函数时,会将n减1,并将n与递归返回值相乘。当n较大时,这种递归方式会导致栈空间占用过多,从而引发栈溢出的错误。
#include<stdio.h>
#include<malloc.h>
#define MAXN 1000
void pnext(int a[], int k)
{
int *b, m = a[0];
int i, j, r, carry;
b = (int *)malloc(sizeof(int) * (m + 1));
for(i = 1; i <= m; i++)
{
b[i] = a[i];
}
for(j = 1; j < k; j++)
{
for(carry = 0, i = 1; i <= m; i++)
{
r = (i <= a[0] ? (a[i] + b[i]) : a[i]) + carry;
a[i] = r % 10;
carry = r / 10;
}
if (carry != 0)
{
a[++m] = carry;
}
}
free(b);
a[0] = m;
}
// 计算k!
void write (int *a , int k)
{
printf("%4d! =", k);
for(int i = a[0]; i > 0; i--)
{
printf("%d", a[i]);
}
printf("\n");
}
int main()
{
int Num[MAXN], n;
printf("Enter the number n:");
scanf("%d", &n);
Num[0] = 1;
Num[1] = 1;
write(Num, 1);
for(int i = 2; i <= n; i++)
{
pnext(Num, i);
write(Num, i);
}
}
阶乘结果
加强版
#include <iostream>
#include <cstring>
using namespace std;
// 定义大数的位数
const int MAX = 10000;
// 定义高精度结构体
struct BigInteger {
int len; // 数字的总位数
int num[MAX]; // 数字各个位上的值,num[0]表示最低位
BigInteger() {
memset(num, 0, sizeof(num)); // 初始化所有位为0
len = 0;
}
void clear() { // 清空高精度数字
memset(num, 0, sizeof(num)); // 将所有位清零
len = 0; // 将位数清零
}
// 重载加法运算符
BigInteger operator+(const BigInteger& b) const {
BigInteger res;
res.clear(); // 清空结果
int carry = 0; // 进位变量
for (int i = 0; i < max(len, b.len); i++) {
int sum = num[i] + b.num[i] + carry;
carry = sum / 10;
res.num[i] = sum % 10;
res.len++;
}
if (carry > 0) {
res.num[res.len++] = carry;
}
return res;
}
// 重载乘法运算符
BigInteger operator*(const BigInteger& b) const {
BigInteger res;
res.clear();
int carry = 0;
for (int i = 0; i < len; i++) {
int carry = 0;
for (int j = 0; j < b.len; j++) {
int sum = num[i] * b.num[j] + res.num[i+j] + carry;
carry = sum / 10;
res.num[i+j] = sum % 10;
}
if (carry > 0) {
res.num[i+b.len] += carry;
}
}
res.len = len + b.len - 1;
while (res.len > 0 && res.num[res.len] == 0) {
res.len--;
}
res.len++;
return res;
}
// 重载输出运算符
friend ostream& operator<<(ostream& out, const BigInteger& x) {
if (x.len == 0) {
out << "0";
} else {
for (int i = x.len-1; i >= 0; i--) {
out << x.num[i];
}
}
return out;
}
};
// 求解n的阶乘
BigInteger fact(int n) {
BigInteger res, tmp;
res.clear();
tmp.clear();
res.num[0] = 1;
res.len = 1;
for (int i = 2; i <= n; i++) {
tmp.clear();
int val = i;
while (val > 0) {
tmp.num[tmp.len++] = val % 10;
val /= 10;
}
res = res * tmp;
}
return res;
}
int main() {
int n;
cin >> n;
cout << fact(n) << endl;
return 0;
}
该程序中定义了一个高精度结构体BigInteger,使用该结构体可以方便地实现高精度计算。其中,重载了加法运算符和乘法运算符,以及输出运算符,用于实现高精度数字的加、乘和输出。
求解阶乘时,采用了逐位相乘的策略,将逐个数字拆分成各个位,按位进行乘法运算,并将结果累加得到最终结果。
网友评论