需要按插入顺序设置STL

时间:2015-08-11 13:12:11

标签: c++ stl set

如何按插入顺序存储集合中的元素。 例如。

set<string>myset;

myset.insert("stack");
myset.insert("overflow");

如果打印,则输出为

overflow
stack

需要输出:

stack
overflow

6 个答案:

答案 0 :(得分:8)

一种方法是使用两个容器,一个std::deque按插入顺序存储元素,另一个std::set以确保没有重复项。

插入元素时,先检查它是否在set中,如果是,则将其丢弃;如果不存在,请将其插入dequeset

一种常见的情况是首先插入所有元素,然后处理(不再插入),如果是这种情况,可以在插入过程后释放set

答案 1 :(得分:2)

set是保持插入顺序的错误容器,它将根据排序标准对其元素进行排序,并忘记插入顺序。你必须使用一个有序的容器,如vector,deque或list。如果您还需要关联访问set,则必须同时将元素存储在多个容器中,或使用像boost::multi_index这样的非STL容器,它可以同时维护多个元素顺序。

PS:如果您在将元素插入集合之前对其进行排序,则该集合将使它们按插入顺序排列,但我认为这不会解决您的问题。

如果除了插入订单之外不需要任何订单,您还可以将插入编号存储在存储的元素中,并使其成为排序标准。但是,为什么人们会在这种情况下使用一套装置逃脱我。 ;)

答案 2 :(得分:1)

我是这样做的:

template <class T>
class VectorSet
{
public:
  using iterator                     = typename vector<T>::iterator;
  using const_iterator               = typename vector<T>::const_iterator;
  iterator begin()                   { return theVector.begin(); }
  iterator end()                     { return theVector.end(); }
  const_iterator begin() const       { return theVector.begin(); }
  const_iterator end() const         { return theVector.end(); }
  const T& front() const             { return theVector.front(); }
  const T& back() const              { return theVector.back(); }
  void insert(const T& item)         { if (theSet.insert(item).second) theVector.push_back(item); }
  size_t count(const T& item) const  { return theSet.count(item); }
  bool empty() const                 { return theSet.empty(); }
  size_t size() const                { return theSet.size(); }
private:
  vector<T> theVector;
  set<T>    theSet;
};

当然,可以根据需要添加新的转发功能,并且可以将其转发到两个数据结构中最有效地实现它们的任何一个。如果你要在这上面大量使用STL算法(我还没有到目前为止),你可能还想定义STL期望找到的成员类型,比如value_type等等。

答案 3 :(得分:1)

我只是想知道为什么没有人建议使用Boost MultiIndex这样的好库。这是一个示例,该如何做:

<?php

//Here this is a connect database

$host_name = "localhost";
$db_name = "stackoverflow";
$user_name = "root";
$password = "";

$conn = new PDO("mysql:host=$host_name; dbname=$db_name", $user_name, $password);

$name = 'JOANNE GRACE%'; //Search this name
$sql = "SELECT * FROM search_name WHERE name LIKE ?";
$select = $conn->prepare($sql);
$select->execute([$name]);

$row = $select->rowCount();

echo "The row is : ".$row;

答案 4 :(得分:0)

如果可以使用Boost,一个非常简单的解决方案是使用仅标头的库Boost.Bimap(双向映射)。

请考虑以下示例程序,该示例程序将按插入顺序(try out here)显示您的虚拟条目:

#include <iostream>
#include <string>
#include <type_traits>
#include <boost/bimap.hpp>

using namespace std::string_literals;

template <typename T>
void insertCallOrdered(boost::bimap<T, size_t>& mymap, const T& element) {
  // We use size() as index, therefore indexing with 0, 1, ... 
  // as we add elements to the bimap.
  mymap.insert({ element, mymap.size() });
}

int main() {
  boost::bimap<std::string, size_t> mymap;

  insertCallOrdered(mymap, "stack"s);
  insertCallOrdered(mymap, "overflow"s);

  // Iterate over right map view (integers) in sorted order
  for (const auto& rit : mymap.right) {
    std::cout << rit.first << " -> " << rit.second << std::endl;
  }
}

答案 5 :(得分:0)

您需要的是这个非常简单的标准库。在线编译器链接示例:http://cpp.sh/7hsxo

m_tree_view.setSelectionBehavior(QAbstractItemView::SelectItems);