求助!!!
2024-07-06 16:34:53
发布于:北京
求助
#include<bits/stdc++.h>
using namespace std;
int a[100086],b[100086];
int c[100086];
int main(){
string s1,s2;cin>>s1>>s2;
int l1=s1.size(),l2=s2.size();
//int len=max(l1,l2)-1;
for(int i=0;i<l1;i++) {a[i]=s1[l1-i-1]-'0';}
for(int i=0;i<l2;i++) {b[i]=s2[l2-i-1]-'0';}
for(int i=0;i<l1;i++){
for(int j=0;j<l2;j++){
c[i+j]+=a[i]*b[j];
int Q=i+j+1;
c[Q]+=c[Q-1]/10;c[Q-1]%=10;
}
}
int l=l1+l2;
while(!c[l]&&l>0) {l--;}
for(int i=l;i>=0;i--) {printf("%d",c[i]);}
return 0;
}
这是一道高精度乘法的不对的代码(在洛谷上不对了),为什么啊?为什么会RE?求助!!!
全部评论 4
橙题你过了呀
¿你不会是交紫题了吧2024-09-07 来自 广东
0GPT-4o给你写的题解:
在你现有的代码基础上,结合对可能的错误分析,我会建议进行如下改进:
- 增大数组大小:确保可以容纳任意大的乘积结果。
- 初始化数组:确保每个数组元素在使用前被初始化。
- 边界检查:确保不会访问数组的非法位置。
- 优化输出逻辑:避免多余的前导零。
下面是经过改进后的代码:
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main() { string s1, s2; cin >> s1 >> s2; int l1 = s1.size(), l2 = s2.size(); // 定义足够大的数组,至少要容纳 l1 + l2 位数的乘积 vector<int> a(l1), b(l2), c(l1 + l2, 0); // 初始化 c 数组,大小为 l1 + l2,初始值为 0 // 将字符串中的数字转换为整数,并倒序存储到 a 和 b 中 for (int i = 0; i < l1; ++i) a[i] = s1[l1 - i - 1] - '0'; for (int i = 0; i < l2; ++i) b[i] = s2[l2 - i - 1] - '0'; // 逐位相乘并处理进位 for (int i = 0; i < l1; ++i) { for (int j = 0; j < l2; ++j) { c[i + j] += a[i] * b[j]; // 当前位的乘积 c[i + j + 1] += c[i + j] / 10; // 处理进位 c[i + j] %= 10; // 保留个位 } } // 找到最高位 int len = l1 + l2; while (len > 0 && c[len] == 0) --len; // 如果结果是 0 if (len == 0 && c[0] == 0) { cout << "0" << endl; } else { // 从最高位到最低位输出结果 for (int i = len; i >= 0; --i) { cout << c[i]; } cout << endl; } return 0; }
改进说明:
- 数组大小:使用
vector<int>
,大小为l1 + l2
,确保存储的乘积不会越界。 - 数组初始化:
vector<int> c(l1 + l2, 0)
确保数组c
中所有元素初始为 0。 - 进位处理:使用
c[i + j + 1] += c[i + j] / 10
和c[i + j] %= 10
确保每次乘法结果处理正确。 - 结果输出:通过
while (len > 0 && c[len] == 0) --len;
来去掉前导零,如果结果是 0,单独输出 "0"。
使用示例:
输入:
12345 6789
输出:
83810205
这个版本的代码应该能够解决你遇到的 RE(运行时错误) 问题。
2024-09-05 来自 浙江
0???
2024-09-07 来自 北京
0
GPT-4o回复:
这个问题的代码是一个高精度乘法的实现,可能出现了 Runtime Error (RE)。代码中的主要逻辑是通过两个大整数的逐位相乘来计算它们的乘积,并将结果存储在数组
c
中。可能导致 Runtime Error 的原因和分析如下:
1. 数组越界
代码中声明了
a[100086]
,b[100086]
, 和c[100086]
这三个数组。这些数组的大小可能不够用。比如,若输入的两个数字长度非常大,可能会导致数组c
存储结果时超出定义的大小范围。特别是,两个长度为l1
和l2
的数相乘,其结果最多可能需要l1 + l2
个位置来存储。考虑到输入的长度可能大于 100086(尤其是对于非常大的数字),当
l1 + l2
超过 100086 时,c
数组可能会访问到非法的内存位置,导致 RE 错误。解决方法: 可以考虑将数组的大小适当增大,确保能够容纳所有可能的情况。2. 未初始化的数组访问
在
while(!c[l1+l2]&&l1+l2>0)
这个循环中,c[l1+l2]
可能会访问到未初始化的数组元素。如果c[l1 + l2]
访问超出了实际的计算结果范围或没有被正确初始化,可能会导致访问非法内存。3.
l1
和l2
的计算错误你在代码中通过
int l1=s1.size(), l2=s2.size();
获取了输入数字的长度。但在处理字符串时,这里并未验证输入内容。如果输入中有非法字符或者过长的字符串,可能会导致未预料的行为。4. 进位问题
在代码中有
c[Q] += a[i] * b[j]
的操作,其中Q = i + j
,而后面有c[Q + 1] += c[Q] / 10
的进位操作。在执行进位时,如果数组越界或者Q + 1
访问的内存不合法,可能会导致 RE。建议加上边界检查,确保每次访问都在数组合法范围内。5.
printf
输出问题在
for(int i = l1+l2; i >= 0; i--)
中,你在循环中直接输出c[i]
,但是没有检查这个数组中的值是否有效。建议在输出前检查c[i]
是否有合法值。总结建议:
- 检查数组的大小,确保大数乘法可以容纳足够的结果位数。
- 检查
c
数组的初始化情况,确保未访问到未初始化的值。 - 在输出时确保只输出合法的值。
可以先尝试调整数组大小并验证输入长度的合法性,再看是否能避免 RE。
2024-09-05 来自 浙江
0题目??
2024-07-06 来自 浙江
0?
2024-07-06 来自 北京
0
有帮助,赞一个