[英]Is there a sorted container in the STL?
Is there a sorted container in the STL? STL 中是否有已排序的容器?
What I mean is following: I have an std::vector<Foo>
, where Foo
is a custom made class.我的意思是:我有一个
std::vector<Foo>
,其中Foo
是一个定制的类。 I also have a comparator of some sort which will compare the fields of the class Foo
.我还有一个比较器,可以比较
Foo
类的字段。
Now, somewhere in my code I am doing:现在,在我的代码中我正在做的某处:
std::sort( myvec.begin(), myvec.end(), comparator );
which will sort the vector according to the rules I defined in the comparator.这将根据我在比较器中定义的规则对向量进行排序。
Now I want to insert an element of class Foo
into that vector.现在我想将
Foo
类的元素插入到该向量中。 If I could, I would like to just write:如果可以,我只想写:
mysortedvector.push_back( Foo() );
and what would happen is that the vector will put this new element according to the comparator to its place.并且会发生的是,向量将根据比较器将这个新元素放置到它的位置。
Instead, right now I have to write:相反,现在我必须写:
myvec.push_back( Foo() );
std::sort( myvec.begin(), myvec.end(), comparator );
which is just a waste of time, since the vector is already sorted and all I need is to place the new element appropriately.这只是浪费时间,因为向量已经排序,我需要的只是适当地放置新元素。
Now, because of the nature of my program, I can't use std::map<>
as I don't have a key/value pairs, just a simple vector.现在,由于我的程序的性质,我不能使用
std::map<>
因为我没有键/值对,只有一个简单的向量。
If I use stl::list
, I again need to call sort after every insertion.如果我使用
stl::list
,我再次需要在每次插入后调用 sort 。
Yes, std::set
, std::multiset
, std::map
, and std::multimap
are all sorted using std::less
as the default comparison operation.是的,
std::set
、 std::multiset
、 std::map
和std::multimap
都使用std::less
作为默认比较操作进行排序。 The underlying data-structure used is typically a balanced binary search tree such as a red-black tree.使用的底层数据结构通常是平衡二叉搜索树,例如红黑树。 So if you add an element to these data-structures and then iterate over the contained elements, the output will be in sorted order.
因此,如果您向这些数据结构添加一个元素,然后迭代包含的元素,输出将按排序顺序。 The complexity of adding N elements to the data-structure will be O(N log N), or the same as sorting a vector of N elements using any common O(log N) complexity sort.
向数据结构添加 N 个元素的复杂度将是 O(N log N),或者与使用任何常见的 O(log N) 复杂度排序对 N 个元素的向量进行排序相同。
In your specific scenario, since you don't have key/value pairs, std::set
or std::multiset
is probably your best bet.在您的特定场景中,由于您没有键/值对,因此
std::set
或std::multiset
可能是您最好的选择。
I'd like to expand on Jason's answer .我想扩展杰森的回答。 I agree to Jason, that either
std::set
or std::multiset
is the best choice for your specific scenario.我同意 Jason 的观点,即
std::set
或std::multiset
是您特定场景的最佳选择。 I'd like to provide an example in order to help you to further narrow down the choice.我想提供一个示例,以帮助您进一步缩小选择范围。
Let's assume that you have the following class Foo
:假设您有以下类
Foo
:
class Foo {
public:
Foo(int v1, int v2) : val1(v1), val2(v2) {};
bool operator<(const Foo &foo) const { return val2 < foo.val2; }
int val1;
int val2;
};
Here, Foo
overloads the <
operator.在这里,
Foo
重载了<
操作符。 This way, you don't need to specify an explicit comparator function.这样,您无需指定显式比较器函数。 As a result, you can simply use a
std::multiset
instead of a std::vector
in the following way.因此,您可以通过以下方式简单地使用
std::multiset
而不是std::vector
。 You just have to replace push_back()
by insert()
:你只需
push_back()
insert()
替换push_back()
insert()
:
int main()
{
std::multiset<Foo> ms;
ms.insert(Foo(1, 6));
ms.insert(Foo(1, 5));
ms.insert(Foo(3, 4));
ms.insert(Foo(2, 4));
for (auto const &foo : ms)
std::cout << foo.val1 << " " << foo.val2 << std::endl;
return 0;
}
Output:输出:
3 4
3 4
2 42 4
1 51 5
1 61 6
As you can see, the container is sorted by the member val2
of the class Foo
, based on the <
operator.如您所见,容器根据
<
运算符按Foo
类的成员val2
排序。 However, if you use std::set
instead of a std::multiset
, then you will get a different output:但是,如果您使用
std::set
而不是std::multiset
,那么您将获得不同的输出:
int main()
{
std::set<Foo> s;
s.insert(Foo(1, 6));
s.insert(Foo(1, 5));
s.insert(Foo(3, 4));
s.insert(Foo(2, 4));
for (auto const &foo : s)
std::cout << foo.val1 << " " << foo.val2 << std::endl;
return 0;
}
Output:输出:
3 4
3 4
1 51 5
1 61 6
Here, the second Foo
object where val2
is 4 is missing, because a std::set
only allows for unique entries.此处,缺少
val2
为 4 的第二个Foo
对象,因为std::set
仅允许唯一条目。 Whether entries are unique is decided based on the provided <
operator.条目是否唯一取决于提供的
<
运算符。 In this example, the <
operator compares the val2
members to each other.在此示例中,
<
运算符将val2
成员相互比较。 Therefore, two Foo
objects are equal, if their val2
members have the same value.因此,如果两个
Foo
对象的val2
成员具有相同的值,则它们是相等的。
So, your choice depends on whether or not you want to store Foo
objects that may be equal based on the <
operator.因此,您的选择取决于您是否要存储基于
<
运算符可能相等的Foo
对象。
C++ do have sorted container eg std::set and std::map C++ 确实有排序的容器,例如 std::set 和 std::map
int main()
{
//ordered set
set<int> s;
s.insert(5);
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(7);
s.insert(2);
cout << "Elements of set in sorted order: ";
for (auto it : s)
cout << it << " ";
return 0;
}
Output: Elements of set in sorted order: 1 2 3 5 6 7输出:按排序顺序排列的集合元素:1 2 3 5 6 7
int main()
{
// Ordered map
std::map<int, int> order;
// Mapping values to keys
order[5] = 10;
order[3] = 5;
order[20] = 100;
order[1] = 1;
// Iterating the map and printing ordered values
for (auto i = order.begin(); i != order.end(); i++) {
std::cout << i->first << " : " << i->second << '\n';
}
Output:输出:
1 : 1 1 : 1
3 : 5 3 : 5
5 : 10 5 : 10
20 : 100 20 : 100
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.