OJ: 4236
高精度乘法的主要步骤:
1、字符串形式读入两个高精度数(因为大数可能很位数很长,所以用字符串)。
2、将两个高精度数按数位拆分后,逆序存储到两个数组中。
3、模拟乘法竖式,枚举两个乘数的每一位分别相乘,将结果统计到积的对应位。
4、从低到位依次处理进位的问题。
5、从高到低依次输出结果。
(1) i=0, j=0, Ans[i+j]+=A[i]*B[j], Ans[0]>9. Ans[i+j+1]=Ans[1]=Ans[0]/10=2 Ans[0]=Ans[0]%10=1
(2) i=0, j=1, Ans[i+j]+=A[i]*B[j], Ans[1]=Ans[1]+A[0]*B[1]=2+12=14. Ans[2]+=Ans[1]/10=1. Ans[1]=Ans[1]%10=4
(3) i=1, j=0, Ans[i+j]+=A[i]*B[j],Ans[1]=Ans[1]+A[1]*B[0]=4+35=39. Ans[2]+=Ans[1]/10=4. Ans[1]=9
(4). i=1, j=1, Ans[i+j]+=A[i]*B[j],Ans[2]=Ans[2]+A[1]*B[1]=4+20=24 . Ans[3]+=Ans[2]/10=2. Ans[2]=Ans[2]%10=4
(5). Ans={1,9,4,2}. 从低位向高位输出,最终得到53*47=2491
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /**************************************************************** * 代码作者: Alex Li * 创建时间: 2024-01-31 05:33:59 * 最后修改: 2025-03-29 18:23:08 * 文件描述: 大数乘法 ****************************************************************/ #include <string> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int MAXN = 1000; int A[MAXN], B[MAXN], Ans[MAXN * 2] = {0}; int Len_A, Len_B, Len_Ans; void Read(int *arr, int &len) { string cur; cin >> cur; len = cur.length(); for (int i = 0; i < len; ++i) { arr[i] = cur[i] - '0'; } reverse(arr, arr + len); } int main() { memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B)); Read(A, Len_A); Read(B, Len_B); Len_Ans = Len_A + Len_B; // 乘积的最大可能位数 // 乘法运算,直接处理进位到Ans[i+j+1] for (int i = 0; i < Len_A; ++i) { for (int j = 0; j < Len_B; ++j) { Ans[i + j] += A[i] * B[j]; // 计算乘积并累加 // 直接处理进位 if (Ans[i + j] > 9) { Ans[i + j + 1] += Ans[i + j] / 10; // 进位到高位 Ans[i + j] %= 10; // 保留个位数 } } } // 去除前导零 while (Len_Ans > 1 && Ans[Len_Ans - 1] == 0) { Len_Ans--; } // 输出结果 for (int k = Len_Ans - 1; k >= 0; --k) { cout << Ans[k]; } return 0; } |
方法二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /**************************************************************** * Description: 大数乘法 * Author: Alex Li * Date: 2023-07-08 17:32:17 * LastEditTime: 2024-06-11 08:06:58 ****************************************************************/ #include <iostream> // 引入输入输出流库 #include <cstring> // 引入字符串处理库 #include <cstdio> // 引入C标准输入输出库 using namespace std; char a1[101], b1[101]; // 定义字符数组,用于存储输入的两个大数字符串 int a[101], b[101], c[10001]; // 定义整型数组,用于存储反转后的数字和结果 int main() { int lena, lenb, lenc, i, j, x; // 定义变量:数字长度及循环控制变量 // 输入两个大数字符串 scanf("%s", a1); scanf("%s", b1); // 获取字符串长度 lena = strlen(a1); lenb = strlen(b1); // 将字符串反转并转换为数字存储在数组中,a和b从数组最后一个元素开始存储,即个位 for (i = 0; i <= lena; i++) a[lena - i] = a1[i] - 48; for (i = 0; i <= lenb; i++) b[lenb - i] = b1[i] - 48; // 进行大数乘法运算 for (i = 1; i <= lena; i++) { x = 0; // 用于存储进位 for (j = 1; j <= lenb; j++) { c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1]; // 计算当前位置的乘积及进位 x = c[i + j - 1] / 10; // 计算新的进位 c[i + j - 1] %= 10; // 当前位只保留个位数 } c[i + lenb] = x; // 最后的位置保存进位 } // 计算结果的实际长度(去掉前导零) lenc = lena + lenb; while (c[lenc] == 0 && lenc > 1) lenc--; // 输出结果 for (i = lenc; i >= 1; i--) cout << c[i]; cout << endl; return 0; } |