Как обнаружить первый или последний элемент, повторяющийся над контейнером? - PullRequest
2 голосов
/ 14 апреля 2010

Как сделать следующее более стильно / коротко?

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

Допустимы такие решения, как foreach (хотя действия над первым и последним элементами должны быть настраиваемыми).

P.S. Есть много ответов, которые обрабатывают первый элемент, но не последний. Вот что я имею в виду под обработкой последнего элемента:

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

Не думаете ли вы, что очень легко обработать первый элемент вне тела цикла? Настоящая проблема - последняя! Я извиняюсь за то, что не смог уточнить важный момент, задавая вопрос. Я думаю, что в конце концов просто приму ответ высшего ранга.

Ответы [ 7 ]

3 голосов
/ 14 апреля 2010

Повышение имеет следующий / предыдущий , который иногда может помочь в таких ситуациях.

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

Хотя для этого конкретного случая я просто вывел бы первый элемент, цикл от второго до последнего, всегда выводя ',', а затем вывел бы '!' после окончания цикла (как уже предлагали другие)

Я не вижу смысла перемещать особые случаи внутри цикла, а затем проверять их внутри цикла ...

3 голосов
/ 14 апреля 2010

Мой совет: Нет смысла что-либо обнаруживать в этом цикле!

Поскольку ваши особые случаи находятся в начале и в конце вашего контейнера, их обработку легко удалить из цикла.

Следующая функция напечатает содержимое любого класса контейнера, элементы которого могут быть << ', преобразованы в 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;
    }
}
2 голосов
/ 14 апреля 2010

Поскольку 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, ", " ) << "!";
2 голосов
/ 14 апреля 2010

В вашем коде

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

никогда не случится.

Мой собственный подход заключается в использовании размера контейнера (я думаю, что size () теперь является постоянным временем для всех контейнеров стандартной библиотеки). Сохраняйте счет в цикле, и вы в конце, когда count == size () - 1, и в начале, когда count == 0, очевидно.

1 голос
/ 14 апреля 2010

Возьмите вторую часть из цикла.

for(i=container.begin(); i!=container.end(); ++i) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
}
cout << "!" << endl; 
1 голос
/ 14 апреля 2010
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;
  }
1 голос
/ 14 апреля 2010

Сдвиньте ++i немного:

i = container.begin();
while(i != container.end()) {
    if (i != container.begin()) {
        cout << ", ";
    }
    cout << *i;
    if (++i == container.end()) {
        cout << "!" << endl; 
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...