c ++ std :: vector检查第一个或最后一个元素

时间:2015-05-13 03:30:59

标签: c++ c++11

我有以下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;
    }

IfLast()当然不存在IfFirst()std::vector。是否有本地std::方法来检查第一个和最后一个元素?

8 个答案:

答案 0 :(得分:19)

在这种情况下你不应该使用基于范围的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
    }
}

请注意,只有在您确定向量中没有重复项时,只需将my.Vector.back()与基于范围的元素进行比较即可。但是,例如,最后一个元素的值在向量中出现多次,您将只找到它的第一个位置。所以这就是为什么没有一个好的方法来使用基于范围的for而没有额外的索引来跟踪你在矢量中的确切位置。

编辑另请参阅@ thelink2012关于如何“欺骗”基于范围的for的答案,以便您可以隐式获取元素的位置。

答案 1 :(得分:19)

使用std::vector::frontstd::vector::back为第一个和最后一个位置的数据获取引用

引用是一个关键字,因为您可以有效地检查迭代item的地址以及相应的前/后引用的地址。在你的例子中,你取item的值而不是引用,所以这个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;
}

如果对象重载了运算符& 的地址(虽然这被认为是一种不好的做法),您可能想要使用std::addressof

然而,对于std::vector<bool>专门化,此方法不起作用,因为它优化了向量以有效地使用位存储布尔值,并且由于我们不能引用位,因此所有引用此数据结构的引用都是代理对象并不完全依赖于内部数据的地址。

答案 2 :(得分:5)

使用std::vector::front()作为第一个元素 使用std::vector::back()作为最后一个元素。

在致电这些功能之前,请确保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

答案 3 :(得分:3)

对于基于价值的比较,您可以使用myVector.front() / myVector[0]作为第一个元素,myVector.back() / myVector[myVector.size()-1]作为最后一个元素。

<强>建议
默认捕获引用以避免不需要的副本。 e.g。

for(const auto& I : myVector)

答案 4 :(得分:2)

您可以再次搜索它,但这样效率会相当低。如果需要有关当前项的位置的信息,可能需要使用迭代器或索引:

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;
}

答案 5 :(得分:2)

如果您有边界的特殊情况,则应使用ol'迭代器版本,但将第一个和最后一个案例与循环分开。

如果案例之后共享代码,则应将其封装在函数上。

我无法通过手机编写代码:c

答案 6 :(得分:0)

这对我有用

vector<int> vi {1,2,3,4};

cout << "vi = {";
for (const auto &e : vi) {
  cout << e;

  if (&e != &vi.back())
    cout << ',';
}
cout << '}' << endl;

答案 7 :(得分:0)

vector<int> vi {1,2,6,4,5,6};

cout << "vi = {";

for (const auto &e : vi) 
{
  cout << e;

  if (&e != &vi.back())

    cout << ',';
}
cout << '}' << endl;

这对于第三个字符与最后一个字符不起作用。