数组组成最大数的代码测试用例未覆盖问题求助
你的思路方向是对的——通过比较ab和ba的拼接结果来排序数组元素,但代码里存在几个关键问题,导致部分测试用例未通过,我来逐一拆解:
1. pow函数的精度陷阱
你的concade函数依赖pow(10, len(b))计算位数对应的10次幂,但pow是浮点数函数,会出现精度丢失的问题。比如当len(b)=3时,pow(10,3)可能返回999.9999999999999,强制转换为long long后就变成了999,而非预期的1000。这会直接导致拼接结果错误,比如a=123、b=45时,本该得到12345,实际会算出123*999+45=122922,彻底打乱比较逻辑。
修复方案:用整数循环代替浮点数pow计算10次幂:
ll concade(ll a, ll b) { ll temp = b; ll power = 1; while (temp > 0) { power *= 10; temp /= 10; } return a * power + b; }
2. 全0场景的处理缺失
当输入全为0时(比如n=3,输入0 0 0),你的代码会输出000,但正确结果应该是0。另外,你额外添加的0交换逻辑是冗余的——因为concade(0, x)等于x,concade(x,0)等于x*10,显然x*10 > x,正常的比较逻辑已经能把非0元素放到前面,不需要额外判断。
修复方案:排序完成后先检查第一个元素是否为0,如果是,直接输出0即可,无需遍历输出所有元素。
3. 大数拼接的溢出问题
long long的最大值是9223372036854775807(约9e18),如果两个待拼接的数都很大(比如两个10位的数1000000000),拼接后的结果是10000000001000000000(19位),会超出long long的范围,导致溢出,比较结果完全错误。
更稳妥的替代方案:放弃整数拼接,改用字符串拼接后比较。字符串比较逻辑直观且无溢出风险,比如比较to_string(a)+to_string(b)和to_string(b)+to_string(a)的字典序(按降序排序即可)。
4. 冒泡排序的冗余判断
你在冒泡排序中先判断arr[j] == 0 && arr[j+1] !=0就交换,这一步多余且可能干扰正常比较逻辑。比如arr[j]=0、arr[j+1]=10时,concade(0,10)=10,concade(10,0)=100,显然100>10,正常比较会自动把10放到前面,不需要额外交换。
修复后的完整示例代码
这里给出用字符串比较的版本,彻底解决上述所有问题:
#include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; bool compare(const string &a, const string &b) { return a + b > b + a; } int main() { int n; while (cin >> n) { if (n == 0) break; vector<string> arr(n); bool all_zero = true; for (int i = 0; i < n; i++) { cin >> arr[i]; if (arr[i] != "0") all_zero = false; } if (all_zero) { cout << "0" << endl; continue; } sort(arr.begin(), arr.end(), compare); for (const string &s : arr) { cout << s; } cout << endl; } return 0; }
这个版本通过字符串比较避免了精度和溢出问题,同时处理了全0的特殊场景,应该能通过所有测试用例。
内容的提问来源于stack exchange,提问作者Anar Abiyev

