STL排序不起作用

时间:2013-03-24 14:12:46

标签: c++ sorting stl

for (i = 0; i < t; i++)
{
  values.clear();

  scanf("%d %d %d", &values[0], &values[1], &values[2]);
  printf("%d %d %d\n", values[0], values[1], values[2]);
  sort(values.begin(), values.end());
  printf("%d %d %d\n", values[0], values[1], values[2]);

  printf("Case %d: %d\n", i + 1, values[1]);
}

我有那个小片段。我输入“1200 1500 1800”它应该给我中间值 - 1500.但是,它输出1200,最小值。

我做的是使用STL的sort()对矢量进行排序,然后打印值[1],这是中间值。

但是,sort()似乎根本不起作用,之前和之后的打印矢量是一样的。

我用以下内容声明我的向量:

vector<int> values (3);

我尝试用vector<int> values;然后push_back(0)三次声明它。

我想知道为什么它不能以第一种方式工作。

5 个答案:

答案 0 :(得分:6)

您的程序有未定义的行为

要修复它,只需删除此行:

values.clear();

上述行的作用实际上是擦除矢量中的所有元素。然后,这一行:

scanf("%d %d %d", &values[0], &values[1], &values[2]);
                   ^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^

将尝试访问不存在的元素。与关联容器的operator []不同,向量的operator []不会创建任何新元素。因此,表达式values[0]values[1]values[2]都是尝试访问不存在的元素。

根据C ++ 11标准的表101:

  

表达式a[n]

     

返回类型:引用;常量const_reference

a      

操作语义 *(a.begin() + n)

这意味着通过这样做:

values[0]

你实际上是这样做的:

*(values.begin() + 0)

此处对values.begin()的调用会返回数组中第一个元素的迭代器。由于向量中没有元素(第23.2.1 / 6节),对values.begin()的调用等同于对values.end()的调用:

  

begin()返回一个迭代器,引用容器中的第一个元素。 end()返回一个迭代器   是容器的过去值。如果容器为空,则为begin() == end();

因此,您案例中的values[0]实际上与此相同:

*(values.end() + 0)

这又相当于:

*(values.end())

换句话说,您正在取消引用指向容器中最后一个元素之外的位置的迭代器。这是未定义的行为,当然同样适用于values[1]values[2]

答案 1 :(得分:5)

values.clear();

这会清除values,使其不再包含任何元素。试图访问任何元素将导致未定义的行为,std::sort将简单地对空数字序列进行排序。

其中a.clear()是序列容器的a的定义是:

  

销毁a中的所有元素。使所有引用,指针和迭代器无效,引用a的元素,并可能使过去的迭代器无效。
  帖子a.empty()返回true

答案 2 :(得分:1)

我认为&lt; __中位数算法&gt; 标题更容易。

med = __median(a, b, c);

答案 3 :(得分:0)

当您清除vector时,您将大小设置为0. scanf行通常不会崩溃,因为vector通常会预先分配一些存储读取值的存储空间。结果是,当您致电sort时,begin()end()将是平等的。

您可以尝试将值读入临时值,或在阅读vaules之前调用resize(3)

答案 4 :(得分:0)

您尝试使用values.clear();清除实际现有元素实际上是将它们完全从向量中移除。这会使begin()end()相等,导致排序无效(以及您将各种元素的地址设置为具有未定义行为的输入)。

我认为你真正想要做的是确保向量中没有太多元素,所以不要clear使用resizevalues.resize(3)如果它当前较小,则具有去除多余元素或将向量的大小增加到3的效果。