我是一名Java开发人员。我正在学习C ++。我一直在寻找代码样本进行排序。在Java中,通常会给排序方法提供排序所需的容器,例如
sort(Object[] someArray)
我在C ++中注意到你传递了两个args,即容器的开头和结尾。我的问题是如何访问实际的容器呢?
以下是维基百科的示例代码,说明了排序方法
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> vec;
vec.push_back(10); vec.push_back(5); vec.push_back(100);
std::sort(vec.begin(), vec.end());
for (int i = 0; i < vec.size(); ++i)
std::cout << vec[i] << ' ';
}
答案 0 :(得分:3)
vec.begin()
和vec.end()
正在返回迭代器迭代器。迭代器是元素的指针,你可以读取它们并使用迭代器修改它们。这就是使用迭代器做的事情。
如果是迭代器,则可以直接修改迭代器引用的对象:
*it = X;
sort函数不必了解容器,这是迭代器的强大功能。通过操纵指针,它可以对整个容器进行排序,甚至不知道它究竟是什么容器。
您应该了解迭代器(http://www.cprogramming.com/tutorial/stl/iterators.html)
答案 1 :(得分:2)
vec.begin()
和vec.end()
不会返回vector
的第一个和最后一个元素。它们实际上返回了所谓的迭代器。迭代器的行为非常类似于指向元素的指针。如果你有一个用i
初始化的迭代器vec.begin()
,你可以通过i++
得到一个指向向量中第二个元素的指针 - 就像你有一个指向数组中的第一个元素。同样,您可以i--
向后退。对于某些迭代器(称为随机访问迭代器),您甚至可以i + 5
执行i
之后的第5个元素的迭代器。
这是算法访问容器的方式。它知道它应该排序的所有元素都在begin()
和end()
之间。它通过执行简单的迭代器操作来导航元素。然后,它可以通过执行*i
来修改元素,这为算法提供了i
指向的元素的引用。例如,如果i
设置为vec.begin()
,而您*i = 5;
,则会更改vec
的第一个元素的值。
此方法允许您仅传递vector
的部分进行排序。假设您只想对vector
的前5个元素进行排序。你可以这样做:
std::sort(vec.begin(), vec.begin() + 5);
这非常强大。由于迭代器的行为与指针非常相似,因此您实际上也可以传递普通的旧指针。假设您有一个数组int array[] = {4, 3, 2, 5, 1};
,您可以轻松调用std::sort(array, array + 5)
(因为数组的名称将衰减为指向其第一个元素的指针)。
答案 2 :(得分:1)
容器无法访问。这就是标准模板库(它成为C ++标准库的一部分)背后的设计的全部要点:算法对容器,只是迭代器一无所知。
这意味着它们可以处理任何提供一对迭代器的东西。当然,所有STL容器都提供begin()
和end()
方法,但您也可以使用常规的旧C数组,MFC或glib容器或其他任何东西,只需为它编写自己的迭代器即可。 (对于C数组,对于开始和结束迭代器,它就像a
和a+a_len
一样简单。)
关于它如何在幕后工作:迭代器遵循一个隐式协议:你可以做++it
之类的事情来将迭代器推进到下一个元素,或者*it
来获取当前的值element,或*it = 3
来设置当前元素的值。 (它比这更复杂,因为有一些不同的协议 - 迭代器可以是随机访问或仅向前,const或可写等。但这是基本的想法。)因此,如果`sort被编码为限制它本身就是迭代器协议(当然,它是),它适用于任何符合该协议的东西。
要了解更多信息,互联网上(和书店)有很多教程;只有这么多的答案可以解释。
答案 3 :(得分:0)
begin()
和end()
返回迭代器。参见例如http://www.cprogramming.com/tutorial/stl/iterators.html
答案 4 :(得分:0)
迭代器的作用类似于容器的一部分。也就是说,*iter = z;
实际上更改了容器中的一个元素。
std::sort
实际上对包含对象的引用使用swap
函数,因此您已经初始化的任何迭代器都保持相同的顺序,但迭代器引用的值会更改。
请注意,std::list
也有名为sort
的成员函数。它的工作方式相反:您已初始化的任何迭代器都保持相同的值,但这些迭代器的顺序会发生变化。