【问题标题】:Accessing Values after Sorting Vector对向量排序后访问值
【发布时间】:2021-07-12 23:50:36
【问题描述】:

我根据排序列表的索引对数据元素进行排序。当我需要对数据进行第二次或第三次排序时,每次都需要将数据的原始顺序重新排序。如何再次访问以原始顺序存储的值?

decltype(m_data) new_m_datalast;
vector<int> m_newOrder;


for(int i=0; i< (int) m_data.size(); ++i)
    new_m_datalast.push_back(std::move(m_data[m_newOrder[i]]));

m_data = new_m_datalast;

更新

 void Canvas::SetSortedOrder(std::vector<int> idxs)
  {
   m_newAxesOrder.clear();
   m_newAxesOrder = idxs;

   m_minmaxdata.clear();
   QString filename(":/simdata/minmax.csv");
   m_minmax = ReadCSV(filename);

  decltype(m_data) new_m_data;
  decltype(m_minmaxdata) new_m_minmaxdata;

  for(int i=0; i< (int) m_data.size(); ++i)
    new_m_data.push_back(std::move(m_data[m_newAxesOrder[i]]));

  for(int i=0; i< (int) m_minmaxdata.size(); ++i)
    new_m_minmax.push_back(std::move(m_minmax[m_newAxesOrder[i]]));

   m_data = new_m_data;
   m_minmax = new_m_minmax;
 }

【问题讨论】:

  • 您需要在排序前制作一份副本。但是如果你要再次对数据进行排序,为什么还需要按原来的顺序呢?
  • 这没有任何意义除非你依赖于稳定的排序。如果不是,你可以用新的标准重新排序,忘记原来的顺序,反正它会被扔掉。
  • 或者,您可以创建一个索引向量(初始化为 1, 2, ... N)并在排序期间应用与应用于主向量相同的转换。然后你就有了新旧职位之间的对应关系。不过这很繁琐,因为您需要一个代理类型才能将其与 std::sort 一起使用。
  • @paul 因为我有另一个使用原始顺序的向量,与我排序的数据一起工作。你能举个例子说明如何复制吗?
  • auto copy_of_vector = original_vector;

标签: c++ sorting


【解决方案1】:

如果您需要多次排序并稍后访问原始数据,建议您使用tag sort。这是一个小的 C++ 示例:

template<typename T>
std::vector<size_t> tag_sort(const std::vector<T>& arr) {
    std::vector<size_t> tag(arr.size());
    std::iota(tag.begin(), tag.end(), 1);

    std::sort(tag.begin(), tag.end(), [&arr](auto a, auto b) { return arr[a] < arr[b]; });

    return tag;
}

int main() {
    std::vector<int> arr = {5, 7, 2, 5, 9, 6, 1};

    auto tag = tag_sort(arr);

    for (auto v : tag) 
        std::cout << v << " ";

    std::cout << "\nsorted data:\n";

    for (auto v : tag) 
        std::cout << arr[v];

    std::cout << "\n";
}

如您所见,您可以访问arr中的原始数据,并使用tag向量来使用排序数据。

标签排序主要用于通过移动/复制切换元素非常昂贵的情况。但我认为这也是解决您的问题的好方法。

【讨论】:

    【解决方案2】:

    我确信这种方式不是最好的。但无论如何我都会这样做。我创建了一个vector&lt;pair&lt;int,int&gt;&gt; v,然后将要排序的数据放入first 中,例如:v[i].first = data,并将它们的索引放入second,例如:v[i].second = i,然后我对向量进行排序或按照我的喜好对其进行处理。而且我可以随时访问其原始订单。

    注意:使用sort(v.begin(),v.end())会默认按pair的first排序,不需要做比较函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      相关资源
      最近更新 更多