目录
1.题目要求
2.题目解读
3.代码实现
4.一些小细节
1.数组储存大整数方式
2.memset函数介绍
3.digit与sum的关系
1.题目要求
2.题目解读
这道题本质就是高精度乘法+高精度加法的结合,我之前有出过
高精度算法-保姆级讲解
希望详细了解的小伙伴可以去看看~
这篇我写的代码其实没有按照之前写过的来写,而是用c语言中的结构体+数组实现的(也算是练手巩固吧)
代码里都有超详细注释,后面还会贴上一些初学者可能会困惑的小细节~
3.代码实现
#include <stdio.h>//以上面你解题的代码为例,为我详细讲解结构体
#include <string.h>
// 定义结构体表示大整数,模拟高精度数
struct BigInteger {
int digit[1000]; // 假设足够存储大整数的每一位,可根据实际调整大小
int len; // 记录大整数的长度
};
// 初始化大整数,将其设置为0
void initBigInteger(struct BigInteger *num) {
memset(num->digit, 0, sizeof(num->digit));
num->len = 1;
}
// 高精度加法,模拟手工加法运算过程
void addBigInteger(struct BigInteger *a, struct BigInteger b) {
int carry = 0;//进位值
int i;
for (i = 0; i < a->len || i < b.len; ++i) {
int sum = carry;//sum变量是当前位相加的结果数字和进位值的和
if (i < a->len) sum += a->digit[i];
if (i < b.len) sum += b.digit[i];
a->digit[i] = sum % 10;
carry = sum / 10;
}
//当循环结束后,如果carry仍然大于 0,这意味着在最高位相加后还有进位。此时需要把这个进位存储到a大整数的更高一位上。
if (carry > 0) {
a->digit[i] = carry;//此时 i 还是原来循环结束时的值,代表着当前大整数的末尾位置的下一个位置,也就是要存放进位的正确下标处
i++;//方便处理下一位数字的操作
}
a->len = i;//更新大整数的长度为 i,确保长度反映了当前大整数的实际位数。
}
// 高精度乘法,模拟手工乘法运算过程
void multiplyBigInteger(struct BigInteger *a, int b) {
int carry = 0;
for (int i = 0; i < a->len; ++i) {
int temp = a->digit[i] * b + carry;
a->digit[i] = temp % 10;
carry = temp / 10;
}
while (carry > 0) {
a->digit[a->len++] = carry % 10;
carry /= 10;
}
}
int main() {
int n;
scanf("%d", &n);
struct BigInteger sum, factorial;
initBigInteger(&sum);
for (int i = 1; i <= n; ++i) {
initBigInteger(&factorial);
factorial.digit[0] = 1;
factorial.len = 1;
for (int j = 1; j <= i; ++j) {
multiplyBigInteger(&factorial, j);
}
addBigInteger(&sum, factorial);
}
for (int i = sum.len - 1; i >= 0; --i) {
printf("%d", sum.digit[i]);
}
printf("\n");
return 0;
}
4.一些小细节
1.数组储存大整数方式
2.memset函数介绍
3.digit与sum的关系
***新人博主创作不易,希望大家多多点赞关注呀~