使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题

Trouble in sorting vector strings using std::sort() using custom compare function

本文关键字:排序 字符串 问题 函数 比较 自定义 std sort      更新时间:2023-10-16

我正在尝试根据规则对字符串进行排序。c++代码在大多数情况下都能工作,但在某些情况下会出现错误:

terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_M_construct null not valid

我以前见过这个错误,当我们试图将字符串初始化为null指针或0(在内部转换为null指针(时会发生这种错误。我已经检查过,只有在使用自定义函数进行比较时,才会在排序过程中发生错误。再一次,我不知道为什么它只发生在某些情况下。

代码为:

#include <algorithm>
#include <sstream>
#include <iostream>
#include <vector>
#include <string>
using std::vector;
using std::string;
bool greater(string a, string b) {
int i = 0;
a = a + a[0];
b = b + b[0];
while(i<a.size() && i<b.size()) {
if(a[i] != b[i]) {
if(a[i] - '0' > b[i] - '0')
return true;
else return false;
}
i++;
}

}
string largest_number(vector<string> a) {
std::sort(a.begin(), a.end(), greater);
std::stringstream ret;
for (size_t i = 0; i < a.size(); i++) {
ret << a[i];
}
string result;
ret >> result;
return result;
}
int main() {
int n;
std::cin >> n;
vector<string> a(n);
for (size_t i = 0; i < a.size(); i++) {
std::cin >> a[i];
}
std::cout << largest_number(a);
return 0;
}

它给出错误的情况之一是:

100  
2 8 2 3 6 4 1 1 10 6 3 3 6 1 3 8 4 6 1 10 8 4 10 4 1 3 2 3 2 6 1 5 2 9 8 5 10 8 7 9 6 4 2 6 3 8 8 9 8 2 9 10 3 10 7 5 7 1 7 5 1 4 7 6 1 10 5 4 8 4 2 7 8 1 1 7 4 1 1 9 8 6 5 9 9 3 7 6 3 10 8 10 7 2 5 1 1 9 9 5

解决方案:谢谢你的帮助。发生错误的原因是比较函数在退出循环后没有返回任何内容。这是有效的更新功能。

bool greater(string a, string b) {
int i = 0;
a = a + a[0];
b = b + b[0];
while(i<a.size() && i<b.size()) {
if(a[i] > b[i])
return true;
i++;
}
return false; 
}

我能看到的代码的唯一问题(实际上我在在线编译器中尝试过,它给了我这个警告(是,如果两个字符串相等,你就不会从greater返回任何东西:

bool greater(string a, string b) {
int i = 0;
a = a;
b = b;
while(i<a.size() && i<b.size()) {
if(a[i] != b[i]) {
if(a[i] - '0' > b[i] - '0')
return true;
else return false;
}
i++;
}
// <---- what about here?
}

请尝试插入return语句。(当然,如果两个东西相等,那么两者都不大于另一个,所以特别是它是你想要的return false。(在没有return语句的函数末尾脱落是未定义的行为(除了int main()或任何返回void的函数(,所以当这种情况发生时,你可能会看到任何东西,包括崩溃的类型。

[编辑:正如gst所说,如果一个字符串是另一个字符串的前缀,例如"1""10",你也会达到这一点。因此,你需要更多的代码来测试哪个是哪个,而不仅仅是return false。但你可以看到这一行是否能修复崩溃:这在逻辑上是错误的,但至少不是未定义的行为。]