[英]STL style function to find the middle of an STL container
I ' ma newcomer in C++ and I kindly request for help to resolve an issue. 我是C ++的新手,我请求帮助来解决问题。
I'm writing a simple STL style function , that should return the middle element of sequence (vector, list etc) 我正在编写一个简单的STL样式函数,它应该返回序列的中间元素(向量,列表等)
Here is my function, I try to use the concept of iterator 这是我的函数,我尝试使用迭代器的概念
template <class It, class T> It middle(It first, It last)
{
while(first!=last){
++first;
--last;
}
return first;
}
here is my main, trying to call middle for a vector of ints (I've omitted includes) 这是我的主要,试图调用中间为一个向量的向量(我省略了包括)
int main() {
vector<int>vi;
int x;
cout<<"Enter vector elemets...";
while (cin>>x)
vi.push_back(x);
cout<<endl;
cin.clear();
cout<<"the vector is:"<<endl;
for(int i=0;i<vi.size();++i)
cout<<vi[i]<<" ";
cout<<endl;
vector<int>::iterator first=vi.begin();
vector<int>::iterator last=vi.end();
vector<int>::iterator ii=middle(first,last);
cout<<"The middle element of the vector is: "<<*ii<<endl;
}
When compiling with g++ I get the following error: 使用g ++编译时出现以下错误:
myex21-7.cpp:79: error: no matching function for call to ‘middle(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&)’
Could somebody give me some tips to resolve it? 有人可以给我一些解决方法吗? Thanks for any help in advanced snek
感谢您对高级潜行的任何帮助
How about: 怎么样:
auto middle = container.begin();
std::advance(middle, container.size()/2);
If you have C++11 available, std::next
lets you do the same in one line instead of two. 如果您有C ++ 11可用,
std::next
允许您在一行而不是两行中执行相同的操作。
Also note that in the case of a container that supports random access iterators (eg, std::vector
or std::deque
) this will be relatively efficient (constant complexity instead of linear complexity). 还要注意,在容器支持随机访问迭代器(例如,
std::vector
或std::deque
)的情况下,这将是相对有效的(恒定复杂度而不是线性复杂度)。
Unless this is an exercise, it might be simpler to implement something in terms of std::next
. 除非这是一个练习,否则用
std::next
来实现某些东西可能更简单。 Ignoring for now the special case of containers with an even number of elements, you could use something like this: 暂时忽略具有偶数元素的容器的特殊情况,您可以使用以下内容:
std::vector<SomeType> v = ....;
auto mid = std::next(v.begin(), v.size()/2);
As for the problem with your code, your middle
function template has two parameters: 至于代码的问题,
middle
函数模板有两个参数:
template <class It, class T> It middle(It first, It last) { .... }
But there is no way for the second parameter to be deduced from the function arguments. 但是没有办法从函数参数中推导出第二个参数。 Since the parameter is not needed anyway, you can simply remove it:
由于无论如何都不需要参数,您只需删除它:
template <class It> It middle(It first, It last) { .... }
The other answers here are interesting, but they require access to the container itself. 这里的其他答案很有趣,但它们需要访问容器本身。 To be truly STL style, you should work with iterator ranges.
要成为真正的STL样式,您应该使用迭代器范围。 Here's a solution that does the efficient thing for random access iterators, but also works for forward iterators
这是一个为随机访问迭代器提供高效处理的解决方案,但也适用于前向迭代器
// http://ideone.com/1MqtuG
#include <iterator>
template <typename ForwardIt>
ForwardIt DoMidpoint(ForwardIt first, ForwardIt last, std::forward_iterator_tag)
{
ForwardIt result = first;
// Try to increment the range by 2
bool sawOne = false;
// EDIT: Note improvements to this loop in the comments
while(first != last)
{
++first;
if (sawOne)
{
// If that succeeded, increment the result by 1
++result;
sawOne = false;
}
else
{
sawOne = true;
}
}
return result;
}
template <typename RandomAccessIt>
RandomAccessIt DoMidpoint(RandomAccessIt first, RandomAccessIt last, std::random_access_iterator_tag)
{
return first + (last - first)/2;
}
template <typename ForwardIt>
ForwardIt midpoint(ForwardIt first, ForwardIt last)
{
return DoMidpoint(first, last, typename std::iterator_traits<ForwardIt>::iterator_category());
}
STL中有几种迭代器,vector具有随机访问权限,这意味着你可以通过中间元素得到迭代器
auto middle = v.begin() + v.size()/2;
Assuming first
and last
are iterators to container's begin()
and end()
, then: 假设
first
和last
是容器的begin()
和end()
迭代器,那么:
Iterator middle = first;
std::advance( middle, std::distance( first, last ) / 2 );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.