目录
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的关系
***新人博主创作不易,希望大家多多点赞关注呀~