C++ 检查元素是 std::vector 中的第一个还是最后一个
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30205158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if the element is the first or the last one in an std::vector
提问by Mendes
I have the following for each
C++ code:
我有以下for each
C++ 代码:
for (auto item : myVector)
{
std::cout << item;
if (item == orderBy.IsLast()) // <--- Check if this is the last element
std::cout << "(Is last element) " << std::endl;
else if (item == orderBy.IsFirst()) // <-- Check if this is the first element
std::cout << "(Is first element)" << std::endl;
}
Of course IfLast()
and IfFirst()
do not exist on std::vector
. Is there a native std::
way to check for first and last element ?
当然IfLast()
,IfFirst()
并不存在于std::vector
。是否有一种本地std::
方式来检查第一个和最后一个元素?
采纳答案by vsoftco
You shouldn't use the range-based for
in this case, as this kind of for
"hides" the iterator, and you'd need an additional counter to keep track of the position in vector. You can simply do
for
在这种情况下,您不应该使用基于范围的,因为这种for
“隐藏”迭代器,并且您需要一个额外的计数器来跟踪向量中的位置。你可以简单地做
for(auto it = myVector.begin(); it != myVector.end(); ++it)
{
if(it == myVector.begin()) // first element
{
// do something
}
else if(std::next(it) == myVector.end()) // last element
{
// do something else
}
}
Note that simply comparing my.Vector.back()
with your element from a range-based for is OK only if you're sure that you don't have duplicates in the vector. But if e.g. the value of the last element appears multiple times in the vector, you're going to find only its first position. So that's why there's really no good way of using a range-based for
without an additional index that keeps track of where exactly in the vector you are.
请注意,my.Vector.back()
仅当您确定向量中没有重复项时,才可以简单地与基于范围的元素进行比较。但是如果例如最后一个元素的值在向量中出现多次,你将只找到它的第一个位置。所以这就是为什么在没有for
额外索引的情况下使用基于范围的方法真的没有好方法来跟踪您在向量中的确切位置。
EDITSee also @thelink2012's answer for how to "trick" your range-based for
so you can get the position of the element implicitly.
编辑另请参阅@thelink2012 的答案,了解如何“欺骗”基于范围的内容,for
以便您可以隐式获取元素的位置。
回答by Denilson Amorim
Use the std::vector::front
and std::vector::back
to get a referenceto the data in the first and last positions.
使用std::vector::front
和std::vector::back
获取对第一个和最后一个位置中的数据的引用。
Reference is a keyword here because you could efficiently check the address of your iterating item
and the address of the respective front/back references. In your example you take the item
by value not reference so this prehaps wouldn't work, take in consideration this example that'd work with this method:
Reference 在这里是一个关键字,因为您可以有效地检查迭代item
的地址和相应的前/后引用的地址。在您的示例中,您采用的是item
by 值而不是引用,因此此 prehaps 不起作用,请考虑使用此方法的此示例:
for(auto& item : myVector) // take item by reference
{
std::cout << item;
if (&item == &myVector.back())
std::cout << "(last element) " << std::endl;
else if (&item == &myVector.front())
std::cout << "(first element)" << std::endl;
}
If the object overloads the address of operator &
(though it's considered a bad practice)you might want to use std::addressof
instead.
如果对象重载了运算符的地址&
(尽管这被认为是一种不好的做法),您可能想std::addressof
改用它。
This method won't work however for the std::vector<bool>
specialization since it optimizes the vector to store booleans efficiently with bits, and since we cannot have references to bits, all references taken out this data structure is a proxy object not exactly tied to the address of the internal data.
然而,这种方法不适用于std::vector<bool>
专业化,因为它优化了向量以有效地用位存储布尔值,并且由于我们不能引用位,所以从这个数据结构中取出的所有引用都是一个代理对象,并没有完全绑定到地址内部数据。
回答by R Sahu
Use std::vector::front()
for the first element.
Use std::vector::back()
for the last element.
使用std::vector::front()
的第一个元素。
使用std::vector::back()
最后一个元素。
Before you call those functions, make sure that the vector
is not empty.
在调用这些函数之前,请确保vector
不为空。
if (!orderBy.empty() && item == orderBy.back()) <--- Check if this is the last element
else if (!orderBy.empty() && item == orderBy.front()) <-- Check if this is the first element
回答by iammilind
For value based comparison, you may use myVector.front()
/myVector[0]
as the first and myVector.back()
/myVector[myVector.size()-1]
as the last element.
对于基于值的比较,您可以使用myVector.front()
/myVector[0]
作为第一个元素和myVector.back()
/myVector[myVector.size()-1]
作为最后一个元素。
Suggestion
Capture the reference by default to avoid unwanted copies. e.g.
建议
默认情况下捕获参考以避免不需要的副本。例如
for(const auto& I : myVector)
for(const auto& I : myVector)
回答by isanae
You could search for it again, but that would be rather inefficient. If you need information on the position of the current item, you probably want to use an iterator or an index:
您可以再次搜索它,但这会相当低效。如果您需要有关当前项目位置的信息,您可能需要使用迭代器或索引:
for (std::size_t i=0; i<myVector.size(); ++i)
{
auto& item = myVector[i];
std::cout << item;
if (i == (myVector.size() - 1))
std::cout << "(Is last element) " << std::endl;
else if (i == 0)
std::cout << "(Is first element)" << std::endl;
}
回答by Dietr1ch
If you have special cases for the boundaries you should use the ol' iterator version, but separating the first and last cases away from the loop.
如果您有边界的特殊情况,您应该使用 ol' 迭代器版本,但将第一个和最后一个案例与循环分开。
If the cases share the code after that if you should encapsulate it on a function.
如果案例共享之后的代码,如果您应该将其封装在函数中。
I can't write code from my phone :c
我无法从手机上编写代码 :c
回答by jafox
This works for me
这对我有用
vector<int> vi {1,2,3,4};
cout << "vi = {";
for (const auto &e : vi) {
cout << e;
if (&e != &vi.back())
cout << ',';
}
cout << '}' << endl;