【问题标题】:Failing to sort my array with std::sort and custom comparator无法使用 std::sort 和自定义比较器对我的数组进行排序
【发布时间】:2019-03-18 12:50:20
【问题描述】:
arr.push_back("1"); 
arr.push_back("34"); 
arr.push_back("3"); 
arr.push_back("98"); 
arr.push_back("9"); 
arr.push_back("76"); 
arr.push_back("45"); 
arr.push_back("4"); 

sort(arr.begin(), arr.end(), myCompare); 

//Here is the compare function
int myCompare(string X, string Y) 
{ 
  string XY = X.append(Y); 

  string YX = Y.append(X); 
  return XY.compare(YX) > 0 ? 1: 0; 
} 
//output should be 998764543431

我对例如的排序有些困惑。我们有号码{"1","34","3","98","9","76","45","4"}。当我们第一次比较 2 个字符串时,我们有 2 个选项 134341 因此341 更大,我们将得到 341 作为返回的字符串。

类似地,我们在下一次迭代中获得3341,在下一次迭代中获得983341,在下一次获得9983341,但是当76 到达时,它必须在开头或结尾追加,要么将998334176769983341 这是错误的。我错过了什么吗?

【问题讨论】:

  • 看起来我得到了您期望的答案。你如何打印结果arr
  • for (int i=0; i

标签: c++ arrays string sorting vector


【解决方案1】:

有几个问题。忽略为什么将 int 存储为std::string 的问题?仅当您将在某个时候将非整数数据存储在数组中时,这才有意义。整数比较非常快。 string 比较很慢,几乎永远不会产生想要的结果。

首先,

std::string::append 修改参数。所以,如果我有:

string x = "left";
string y = "right";
string xy = x.append(y);

x 现在等于“leftright”,xy 也是如此。您的比较函数会将 x 附加到 y,然后将 y 附加到结果。

你的方法,用 X = 1, Y = 34 调用:

string XY = X.append(Y); 
// XY = "134", X = "134", Y = "34"
string YX = Y.append(X); 
// YX = 34134, Y = "34134", X = "134"

return XY.compare(YX) > 0 ? 1: 0; 

所以,这可以表示为

X = X + Y;
XY = X;
Y = Y + X;
YX = Y;

string::compare 进行字符比较。因此,如果您的数组仅使用 string::compare 进行排序,您将得到

1       3       34      4       45      76      9       98

第二,

当我们第一次比较 2 个字符串时,我们有 2 个选项 134 和 341,因此 341 更大,我们将得到 341 作为返回的字符串。

“341”大于“134”。但是,您不是在比较“341”和“134”——而是在比较“134”和“3134”。 “3134”只是更大,因为它以 3 而不是“1”开头。如果数字是“1341”和“341”,“341”仍然会更大。

如果您的目标只是根据整数值对列表进行排序,

int myCompare(string X, string Y)
{
    return atoi(X.c_str()) < atoi(Y.c_str());
}

或者,更明智的是,使用 int 数组而不是字符串,并让 sort 使用它的内置比较函数。

【讨论】:

  • 你为什么选择 x=1 和 y=34?如果我们有这个代码 bool compare(int a, int b) { string a1 = to_string(a)+ to_string(b);字符串 b1 = to_string(b)+ to_string(a);返回 a1>b1; } 排序(nums.begin(),nums.end(),比较器);并且 nums 数组是 [3,30,34,5,9] 那么 int a 和 int b 是什么?以及我们将如何在每次迭代中更改它们?
  • @sunidhichaudhary 因为它们是您示例中的前两个元素。他们在某个时候被比较,和其他任何一对一样好。
  • 我对比较器功能的工作方式感到困惑。
  • @sunidhichaudhary 好的。你能详细说明一下“困惑”吗?比较器被重复调用 - 在(大约) O(n^2) 和 O(n log n) 次之间的某个位置 - 对于源中的不同值对。顺序与原始数组的排序关系不大,除非非常特殊的情况,否则不会按照源数组中元素的顺序调用它。 std::sort 通常使用快速排序,(尽管根据规范,我认为这是依赖于实现的)所以谷歌一下。设置断点,单步执行,看看到底发生了什么。
  • 好的,这意味着比较器会为数组中的每个可能对调用,它会检查所有可能性?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
相关资源
最近更新 更多