如何检测在容器上迭代的第一个或最后一个元素?

发布于 2024-08-29 12:21:56 字数 965 浏览 3 评论 0原文

如何以更时尚/简短的方式执行以下操作?

for(i=container.begin(); i!=container.end(); ++i) {
    if (i!=container.begin()) {
        cout << ", ";
    }
    cout << *i;
    j=i;
    if (++j==container.end()) {
        cout << "!" << endl; 
    }
}

foreach 这样的解决方案是可以接受的(对第一个和不过,last 元素需要是可配置的)。

聚苯乙烯 有许多答案正在处理第一个元素,但不是最后一个元素。这就是我所说的处理最后一个元素的意思:

for(i=container.begin(); i!=container.end(); ++i) {
    j=i;
    if (i==container.begin()) {
        cout << "[" << *i << "]" << endl;
    } else if (++j==container.end()) {
        cout << ", (" << *i << ")" << "!" << endl; 
    } else {
         cout << ", " << *i;
    }
}

您不认为处理循环体之外的第一个元素很容易吗?真正的问题是最后一个!我很抱歉无法澄清提出问题的要点。我想我最终会接受排名最高的答案。

How to do the following in more stylish/short way?

for(i=container.begin(); i!=container.end(); ++i) {
    if (i!=container.begin()) {
        cout << ", ";
    }
    cout << *i;
    j=i;
    if (++j==container.end()) {
        cout << "!" << endl; 
    }
}

Solutions like foreach are acceptable (actions on first and last elements need to be configurable, though).

P.S.
There are many answers that are handling first element, but not last. Here is what I mean by handling last element:

for(i=container.begin(); i!=container.end(); ++i) {
    j=i;
    if (i==container.begin()) {
        cout << "[" << *i << "]" << endl;
    } else if (++j==container.end()) {
        cout << ", (" << *i << ")" << "!" << endl; 
    } else {
         cout << ", " << *i;
    }
}

Don't you think it's very easy to handle first element outside the cycle body? The real problem is the last one! I'm sorry for not being able to clarify the important point asking the question. I think I'll just accept the top ranked answer eventually.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

红玫瑰 2024-09-05 12:21:56

Boost 有下一个/之前,有时可以帮助这样的情况。

for(i=container.begin(); i!=container.end(); ++i) {
    if (boost::next(i) == container.end()) {
         std::cout << "!" << std::endl;
    }
}

尽管对于这种特定情况,我只是输出第一个元素,从第二个元素循环到最后一个元素,同时始终输出“,”,然后输出“!”循环结束后。 (正如其他人已经建议的那样)

我不认为将特殊情况移动到循环内,然后在循环内检查它们有什么意义......

Boost has next / prior which can sometimes help in such situations.

for(i=container.begin(); i!=container.end(); ++i) {
    if (boost::next(i) == container.end()) {
         std::cout << "!" << std::endl;
    }
}

Although for this specific case, I'd simply output the first element, loop from second till last while always outputting the ',' and then output the '!' after the loop has ended. (as others have suggested already)

I don't see the point in moving the special cases inside the loop, and then checking inside the loop for them....

心作怪 2024-09-05 12:21:56

我的建议是:检测此循环内的任何内容都是没有意义的!

由于您的特殊情况位于容器的开头和结尾,因此很容易从循环内删除它们的处理。

以下函数将打印其元素可以<<'ed到std::ostream的任何容器类的内容:

template < class Container >
void print(Container const & container)
{
    typename Container::const_iterator current = container.begin();
    typename Container::const_iterator const end = container.end();
    if (current != end)
    {
        std::cout << *current;
        for (++current; current != end; ++current)
        { 
            std::cout << ", " << *current;
        }
        std::cout << "!" << std::endl;
    }
}

My advice here would be: there is no point in detecting anything within this loop !

Since your special cases are at the beginning and the end of your container, it is easy to remove their processing from within the loop.

The following function will print the contents of any container class whose elements can be <<'ed to an std::ostream:

template < class Container >
void print(Container const & container)
{
    typename Container::const_iterator current = container.begin();
    typename Container::const_iterator const end = container.end();
    if (current != end)
    {
        std::cout << *current;
        for (++current; current != end; ++current)
        { 
            std::cout << ", " << *current;
        }
        std::cout << "!" << std::endl;
    }
}
鱼忆七猫命九 2024-09-05 12:21:56

在你的代码中,

if (i==container.end()) {
    cout << "!" << endl; 
}

永远不会发生。

我自己的方法是使用容器大小(我认为 size() 现在对于所有标准库容器来说都是恒定时间)。显然,在循环中维护一个计数,当 count == size() - 1 时,您处于结束状态;当 count == 0 时,您处于循环开始状态。

In your code,

if (i==container.end()) {
    cout << "!" << endl; 
}

will never happen.

My own approach would be to use the container size (I think size() is now constant time for all Standard Library containers). Maintain a count in the loop and you are at the end when count == size() - 1, and at the beginning when count == 0, obviously.

烟花肆意 2024-09-05 12:21:56

由于 container 不是由您定义的,我使用了最简单的 - vector

template <class T>
string vector_join( const vector<T>& v, const string& token ){
  ostringstream result;
  for (typename vector<T>::const_iterator i = v.begin(); i != v.end(); i++){
    if (i != v.begin()) result << token;
    result << *i;
  }
  return result.str();
}

//usage
cout << vector_join( container, ", " ) << "!";

As container is not defined by you, I used the simplest - vector

template <class T>
string vector_join( const vector<T>& v, const string& token ){
  ostringstream result;
  for (typename vector<T>::const_iterator i = v.begin(); i != v.end(); i++){
    if (i != v.begin()) result << token;
    result << *i;
  }
  return result.str();
}

//usage
cout << vector_join( container, ", " ) << "!";
烟火散人牵绊 2024-09-05 12:21:56

稍微移动一下 ++i

i = container.begin();
while(i != container.end()) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
    if (++i == container.end()) {
        cout << "!" << endl; 
    }
}

Shift the ++i a bit:

i = container.begin();
while(i != container.end()) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
    if (++i == container.end()) {
        cout << "!" << endl; 
    }
}
瀟灑尐姊 2024-09-05 12:21:56
template < class TContainerType>
void print(TContainerType const & i_container)
  {
  typename TContainerTypeconst ::const_iterator current = i_container.begin();
  typename TContainerTypeconst ::const_iterator const end = i_container.end();
  if(current != end)
    {
    std::cout << *current++;
    while(current != end)
      std::cout << ", " << *current++;
     }
  std::cout << "!" << std::endl;
  }
template < class TContainerType>
void print(TContainerType const & i_container)
  {
  typename TContainerTypeconst ::const_iterator current = i_container.begin();
  typename TContainerTypeconst ::const_iterator const end = i_container.end();
  if(current != end)
    {
    std::cout << *current++;
    while(current != end)
      std::cout << ", " << *current++;
     }
  std::cout << "!" << std::endl;
  }
苄①跕圉湢 2024-09-05 12:21:56

将第二部分从循环中取出。

for(i=container.begin(); i!=container.end(); ++i) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
}
cout << "!" << endl; 

Take the second part out of the loop.

for(i=container.begin(); i!=container.end(); ++i) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
}
cout << "!" << endl; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文