为何数组构造最大数的C++代码仅部分案例触发SIGABRT错误?
问题分析与解决方案
你的代码触发SIGABRT错误的核心原因是整数溢出引发的未捕获异常,同时还有几个潜在问题需要修正,下面逐一拆解:
1. 崩溃的直接原因:stoi的溢出问题
在你提供的测试案例中,拼接后的字符串会变得很长(比如最终正确结果是6054854654),这个数值远超过了C++中int类型的最大值(2^31-1,即2147483647)。当你调用stoi(s1)或stoi(s2)时,函数会因为无法将超大字符串转换为int而抛出std::out_of_range异常,而你的代码没有捕获这个异常,最终导致程序触发abort信号,也就是你看到的错误。
更关键的是,用数值大小判断拼接后的字符串优先级本身就是错误思路——比如9和90,数值上90>9,但拼接成字符串的话990比909更大,数值比较的结果会直接误导逻辑。
2. 其他潜在问题
- 非标准变长数组(VLA):
int a[n]是GCC的扩展语法,并非C++标准支持的特性,在MSVC等其他编译器下会直接报错,建议改用std::vector存储数据。 - 冗余的字符串转换:每次循环都将
int转string,可以直接读取为字符串减少不必要的操作。
修正后的代码
下面是修复后的代码,核心思路是直接比较字符串拼接结果,完全避开数值转换的溢出风险,同时解决了其他潜在问题:
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main() { int t; cin >> t; while (t-- > 0) { int n; cin >> n; vector<string> strs; // 直接读取为字符串,避免int转string的冗余操作 for (int i = 0; i < n; ++i) { string s; cin >> s; strs.push_back(s); } // 自定义排序规则:a+b比b+a大的话,a排在前面 sort(strs.begin(), strs.end(), [](const string& a, const string& b) { return a + b > b + a; }); // 拼接最终结果 string result; for (const auto& s : strs) { result += s; } // 处理全0的特殊情况(比如输入0 0 0,输出0而非000) if (!result.empty() && result[0] == '0') { cout << "0" << endl; } else { cout << result << endl; } } return 0; }
代码说明
- 自定义排序逻辑:通过
sort结合lambda表达式,直接比较两个字符串拼接后的结果,确保排序后的数组拼接起来是最大的数,彻底避免了数值转换的溢出问题。 - 标准容器使用:用
std::vector<string>存储输入,符合C++标准且更灵活。 - 特殊场景兼容:当所有输入都是0时,会自动输出单个0,避免出现多个0的无效结果。
用你提供的测试案例运行,会输出正确结果6054854654,且不会再出现崩溃问题。
内容的提问来源于stack exchange,提问作者Mahesh Nagarwal
相关产品推荐
相关产品推荐

