比较使用STL排序时的方法问题

时间:2011-03-25 22:40:29

标签: c++ sorting stl

请考虑以下代码。 它应该按字典顺序排序整数向量的矢量, 即首先是第一列,然后是第二列,依此类推。 在我的应用程序中,我只关心8列中的前6个 因此,当前6列的值相等时,返回true。

它引起了问题(分段错误)。它正在为1000个数据工作,它崩溃了1001。 示例代码是玩具,但排序是相当复杂的程序的一部分。 经过长时间的调试,我发现它是造成麻烦的原因。 程序尝试使用一个(1,0,...,0)条目对所有零的数组进行排序。

请问任何C ++专家,你能告诉我原始(上市)程序有什么问题吗?

我正在使用32位Windows上的32位和64位Linux和Visual Studio进行编译。 它总是崩溃。评论发生变化后,一切似乎都很好。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int COLS = 8;

bool compare (const vector<int>& r1, const vector<int>& r2)
{         
   for (int i = 0; i < COLS-2; i++)
     if ( r1[ i ] != r2[ i ] )
      return (r1[ i ] < r2[ i ]);
   return true; //if true is replace by r1[ COLS-1 ] < r2[ COLS-1 ] then is OK
};

int main(int argc, char **argv) 
{       
    int Na = 20;
    vector< vector<int> > v( Na );

    for (int r = 0; r < v.size(); r++)
      v[r].resize(COLS, 0);
    v[0][0] = 1;

    cout << "Sorting\n";
    sort( v.begin(), v.end(), compare );
    cout << "Eof Sorting\n";         

    return 0;
} 

6 个答案:

答案 0 :(得分:4)

我认为你正在筹码。 sort函数是递归实现的,因此如果您对元素之间的顺序关系给出不一致的答案,算法可能无法终止。

答案 1 :(得分:4)

当输入相等时,您的比较函数必须返回false,而不是true

答案 2 :(得分:2)

问题在于你的比较功能:

bool compare (const vector<int>& r1, const vector<int>& r2)
{         
   for (int i = 0; i < COLS-2; i++)
     if ( r1[ i ] != r2[ i ] )
      return (r1[ i ] < r2[ i ]);
   return true; //if true is replace by r1[ COLS-1 ] < r2[ COLS-1 ] then is OK
};

如果元素相等,则表达式r1 < r2false - 但如果相等(在您的情况下,如果前6个整数相等),则返回true

答案 3 :(得分:1)

这不一定与问题有关(它不会导致崩溃),但代码正在跳过一列。代码比较6(8-2)列然后(如果使用未注释的代码),它将比较最后一列。没有检查倒数第二个。但是,这可能是意图......如果是这样的话,如果代码必须存在任何时间,评论可能会很好。

答案 4 :(得分:1)

如果要按字典顺序排序,可以使用标准库:

bool compare (const vector<int>& r1, const vector<int>& r2)
{  
   return std::lexicographical_compare(r1.begin(), r1.begin()+6, r2.begin(), r2.begin()+6);
}

答案 5 :(得分:0)

我希望你在你的某个向量的末尾运行,这将在发布版本中产生未定义的结果。

在Linux上,使用优秀的Valgrind运行您的程序。

您还可以创建代码,以便仅检查向量中的实际插槽,例如:

bool compare (const vector<int>& r1, const vector<int>& r2)
{  
   const int max = std::min(r1.size(),r2.size());
   for (int i = 0; i<max; i++)
     if ( r1[ i ] != r2[ i ] )
      return (r1[ i ] < r2[ i ]);
   return r1.size() < r2.size();
};

但是,如果您期望确切数量的插槽,那么这是一个逻辑错误并使您的比较功能忽略它不一定是一个好的解决方案。