这个排序两个向量作为参考传递给函数

Posted

技术标签:

【中文标题】这个排序两个向量作为参考传递给函数【英文标题】:this sort two vectors passed to function as references 【发布时间】:2020-12-21 11:28:41 【问题描述】:

我尝试使用另一个值对一个向量进行排序, 这是代码:

template <typename T>
    void ordered_by_old_indices(std::vector<T> const& values, std::vector<size_t> &indices) 
        //std::vector<size_t> indices(values.size());
        //std::iota(begin(indices), end(indices), static_cast<size_t>(0));
        //auto x = indices.begin();
        //std::cout << *x << std::endl;
        //auto y = indices.end()-1;
        //std::cout << *y << std::endl;

        std::sort(
            indices.begin(), indices.end(),
            [&](size_t a, size_t b)  return values[a] < values[b]; 
        );
        //return indices;
    

但它给了我错误:

vector subscript out of range

这里有什么问题,它只是排序的包装器???

更新: 问题是 sort 给出了要排序的向量元素的比较函数值,我想要一种方法让 sort 传递元素的位置而不是它的值。这意味着传递 01234567.... 但在给定的向量索引上工作

【问题讨论】:

“向量下标超出范围”就是这个意思。通常人们将其称为越界访问。现在您需要在调试器中捕获异常,并在异常发生时检查所有相关值。 values 似乎比要求的要小。 索引和值的大小相同 在这种情况下,我会在调用std::sort() 之前插入一个assert(values.size() == indices.size());。如果它导致中止,您就会知道它为什么不起作用。如果它没有任何作用,这至少对读者来说是一个有价值的提示。 那你也可以再添加一个:assert([&amp;]() for (size_t i : indices) if (i &gt;= values.size()) return false; return true; ());(抱歉,单行看起来有点丑) 我同意@JHBonarius:我的第一个assert() 有点人手不足。第二个检查indices 中的所有索引是否指向values 中的现有元素。如果失败,indices 中至少有一个索引,这可能导致对values 的越界访问(如果用于例如values[indices[i]] 或用于sort() 的自定义谓词中)。 【参考方案1】:

我认为这应该可行。还在努力中

template <typename T>
    void ordered_by_old_indices(std::vector<T> const& values, std::vector<size_t> &indices) 
        std::vector<size_t> indices_1(indices.size());
        std::iota(begin(indices_1), end(indices_1), static_cast<size_t>(0));
        std::sort(
            begin(indices_1), end(indices_1),
            [&](size_t a, size_t b)  return values[a] < values[b]; 
        );
        assert(values.size() == indices_1.size());
        //assert([&]()  for (size_t i : indices_1)  if (i >= values.size()) return false;  return true; ());

        //std::sort(
        //  begin(indices), end(indices),
        //  [&](size_t a, size_t b)  return indices_1[a] < indices_1[b]; 
        //);
        //now I should use sorted indices_1 to pushback original indices into indices
        for (std::vector<size_t>::iterator indices_1_it = indices_1.begin(); indices_1_it != indices_1.end(); indices_1_it ++)
        
            indices.push_back(values[indices_1[]]);
        
        //return indices;
    

【讨论】:

【参考方案2】:

您的函数有效,见下文,(正如我认为您想要的那样)所以@Scheff 说的是您的索引超出了值的范围。所以试着在你的函数中打印你的索引,看看是否有任何索引[x]会导致值[indices[x]]超出范围。

#include <vector>
#include <algorithm>
#include <numeric>
template <typename T>
void ordered_by_old_indices(std::vector<T> const& values, std::vector<size_t> &indices) 
    std::sort(
        indices.begin(), indices.end(),
        [&](size_t a, size_t b)  return values[a] < values[b]; 
    );
    //return indices;


void TestIndices() 
  std::vector<size_t> values(50);
  std::iota(begin(values), end(values), static_cast<size_t>(0));
  std::random_shuffle(values.begin(), values.end());
  std::vector<size_t> indices(values.size());
  std::iota(begin(indices), end(indices), static_cast<size_t>(0));
  auto x = indices.begin();
  std::cout << *x << std::endl;
  auto y = indices.end()-1;
  std::cout << *y << std::endl;
  ordered_by_old_indices(values, indices);
  std::cout << values.size() << indices.size() << "\n";
  for(int i = 0; i < values.size(); ++i) // print the values ordered by indices
    std::cout << indices[i] << " : " << values[indices[i]] << "\n";

【讨论】:

显示他的解决方案适用于特定输入并不能解决问题。只是说明问题不好,即没有调试细节。 问题是 sort 给出了要排序的向量元素的比较函数值,我想要一种方法让 sort 传递元素的位置而不是它的值。这意味着 pas 01234567 ....但在给定的向量索引上工作 @ahmedallam 我认为您需要提供至少 5 个值的示例输入和输出来澄清问题。

以上是关于这个排序两个向量作为参考传递给函数的主要内容,如果未能解决你的问题,请参考以下文章

将变量名称的向量传递给 dplyr 中的arrange()

如何将向量传递给函数?

我将向量作为双精度传递给函数,但视觉工作室将其称为无符号整数

使用lambda函数进行向量排序,当不在同一范围内时如何传递变量来捕获组?

如何通过将向量元素传递给函数来更改它们

用于对包含指向自定义类对象的指针的向量进行排序的比较器