【问题标题】:custom string sort comparison function weird behavior自定义字符串排序比较函数奇怪的行为
【发布时间】:2018-05-20 00:30:16
【问题描述】:

我需要对一个字符串向量进行排序,但它不是严格的前向排序。我编写了一个自定义排序函数,它非常适用于较小的向量大小(

我添加了一些调试 printf 语句以查看内部发生的情况,我发现空字符串和其他奇怪的字符串正在传递到要排序的函数中。

我的期望是只有向量中的值会被传递到函数中。我验证了向量中填充了已知值。

排序功能:

bool sortFunc( string a, string b ){    
    printf( "a: %s,\tb: %s  \t", a.c_str(), b.c_str() );

    //sorting magic defining 'bool retVal'

    printf( "%s goes before %s\n", retVal?a.c_str():b.c_str(), retVal?b.c_str():a.c_str() );

    return retVal;
}

主要功能:

vector<string> a(n);
for( int i=0; i<n; ++i ){
    cin >> a[i];
}

sort(a.begin(),a.end(),sortFunc);

奇怪的输出示例:

a: 2,   b: 10   2 goes before 10
a: 10,  b: 10   10 goes before 10
a: ,    b: 10    goes before 10
a: ,    b: 10    goes before 10
a: \240E,   b: 10   \240E goes before 10
a: ,    b: 10    goes before 10
a: {@,  b: 10   {@ goes before 10
a: ,    b: 10    goes before 10
a: ,    b: 10    goes before 10
a: ,    b: 10    goes before 10
a: \225E,   b: 10   10 goes before \225E
a: 2,   b: 10   2 goes before 10
a: 10,  b: \225E    10 goes before \225E
a: ,    b:       goes before 
a: ,    b:       goes before 
a: \245E,   b:       goes before \245E
a: \236E,   b: \245E    \245E goes before \236E
a: 0G\260\377, b: \236E    0G\260\377 goes before \236E
a: 0G\260\377, b: \245E    0G\260\377 goes before \245E
a: 0G\260\377, b:      0G\260\377 goes before 

【问题讨论】:

  • (A) 为什么要按值接受字符串? (B) 排序算法很可能有一个临时空间来将字符串移入和移出。移动字符串会使它处于某种未知但有效的状态。 (C) 你有没有想过你的“魔法”可能不是严格的弱排序,就像排序算法所期望的那样?留下未定义行为的代码。
  • 如果在排序之前打印vector&lt;string&gt; a 会怎样?您确定其中没有“奇怪”的值吗?
  • 如果由于retVal 为真(从输出中无法判断)而得到输出“10 在 10 之前”,则您没有严格的弱排序,并且结果未定义。
  • @xander,我之前确实打印过它并检查了 Xcode 中的变量

标签: c++ sorting


【解决方案1】:

std::sort 表现得好笑时,几乎总是因为无效的比较函数。您传递给std::sort 的比较函数必须提供严格的弱排序。通常的失败是比较函数被定义为对于两个对象abcompare(a,b)返回true 并且 compare(b,a)返回true,即a在@之前987654328@ 和 ba 之前。发生这种情况时,排序算法很可能会耗尽您的数据并做各种疯狂和疯狂的事情。

这个问题的实际答案就在这里面:

//sorting magic defining 'bool retVal'

【讨论】:

    猜你喜欢
    • 2011-09-13
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 2021-09-07
    • 2011-04-07
    • 2011-10-07
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多