<< Пред.           стр. 105 (из 121)           След. >>

Список литературы по разделу

  static int _line_cnt;
 };
 
 int print_elements::_line_cnt = 1;
 
 /* печатается:
  исходный список строк:
  The light untonsured hair grained and hued like
  pale oak
 
  после copy_backward( begin+1, end-3, end ):
  The light untonsured hair light untonsured hair grained
  and hued
 */
 
 int main()
 {
  string sa[] = {
  "The", "light", "untonsured", "hair",
  "grained", "and", "hued", "like", "pale", "oak" };
 
  vector< string, allocator > svec( sa, sa+10 );
 
  cout << "исходный список строк:\n\t";
  for_each( svec.begin(), svec.end(), print_elements() );
  cout << "\n\n";
 
  copy_backward( svec.begin()+1, svec.end()-3, svec.end() );
 
  print_elements::reset_line_cnt();
 
  cout << "после copy_backward( begin+1, end-3, end ):\n";
  for_each( svec.begin(), svec.end(), print_elements() );
  cout << "\n";
 }
  Алгоритм count()
 template < class InputIterator, class Type >
 iterator_traits::distance_type
 count( InputIterator first,
  InputIterator last, const Type& value );
 count() сравнивает каждый элемент со значением value в диапазоне, ограниченном парой итераторов [first,last), с помощью оператора равенства. Алгоритм возвращает число элементов, равных value. (Отметим, что в имеющейся у нас реализации стандартной библиотеки поддерживается более ранняя спецификация count().)
 #include
 #include
 #include
 #include
 
 #include
 #include
 #include
 
 /***********************************************************************
 * прочитанный текст:
 Alice Emma has long flowing red hair. Her Daddy says
 when the wind blows through her hair, it looks almost alive,
 like a fiery bird in flight. A beautiful fiery bird, he tells her,
 magical but untamed. "Daddy, shush, there is no such thing,"
 she tells him, at the same time wanting him to tell her more.
 Shyly, she asks, "I mean, Daddy, is there?"
 ************************************************************************
  * программа выводит:
  * count(): fiery встречается 2 раз(а)
 ************************************************************************
 */
 
 int main()
 {
 
  ifstream infile( "alice_emma" );
  assert ( infile != 0 );
 
  list textlines;
 
  typedef list::difference_type diff_type;
  istream_iterator< string, diff_type > instream( infile ),
  eos;
 
  copy( instream, eos, back_inserter( textlines ));
 
  string search_item( "fiery" );
 
  /*********************************************************************
  * примечание: ниже показан интерфейс count(), принятый в
  * стандартной библиотеке. В текущей реализации библиотеки
  * от RogueWave поддерживается более ранняя версия, в которой
  * типа distance_type еще не было, так что count()
  * возвращала результат в последнем аргументе
  *
  * вот как должен выглядеть вызов:
  *
  * typedef iterator_traits::
  * distance_type dis_type;
  *
  * dis_type elem_count;
  * elem_count = count( textlines.begin(), textlines.end(),
  * search_item );
  ***********************************************************************
 
  int elem_count = 0;
  list::iterator
  ibegin = textlines.begin(),
  iend = textlines.end();
 
  // устаревшая форма count()
  count( ibegin, iend, search_item, elem_count );
 
  cout << "count(): " << search_item
  << " встречается " << elem_count << " раз(а)\n";
 }
  Алгоритм count_if()
 template < class InputIterator, class Predicate >
 iterator_traits::distance_type
 count_if( InputIterator first,
  InputIterator last, Predicate pred );
 count_if() применяет предикат pred к каждому элементу из диапазона, ограниченного парой итераторов [first,last). Алгоритм сообщает, сколько раз предикат оказался равным true.
 #include
 #include
 #include
 
 class Even {
 public:
  bool operator()( int val )
  { return val%2 ? false : true; }
 };
 
 int main()
 {
  int ia[] = {0,1,1,2,3,5,8,13,21,34};
  list< int,allocator > ilist( ia, ia+10 );
 
  /*
  * не поддерживается в текущей реализации
  *****************************************************
  typedef
  iterator_traits::distance_type
  distance_type;
 
  distance_type ia_count, list_count;
 
  // счетчик четных элементов: 4
  ia_count = count_if( &ia[0], &ia[10], Even() );
  list_count = count_if( ilist.begin(), ilist_end(),
  bind2nd(less(),10) );
  ******************************************************
  */
  int ia_count = 0;
  count_if( &ia[0], &ia[10], Even(), ia_count );
 
  // печатается:
  // count_if(): есть 4 четных элемент(а).
 
  cout << "count_if(): есть "
  << ia_count << " четных элемент(а).\n";
 
  int list_count = 0;
  count_if( ilist.begin(), ilist.end(),
  bind2nd(less(),10), list_count );
 
  // печатается:
  // count_if(): есть 7 элемент(ов), меньших 10.
 
  cout << "count_if(): есть "
  << list_count
  << " элемент(ов), меньших 10.\n";
 }
  Алгоритм equal()
 template< class InputIterator1, class InputIterator2 >
 bool
 equal( InputIterator1 first1,
  InputIterator1 last, InputIterator2 first2 );
 
 template< class InputIterator1, class InputIterator2,
  class BinaryPredicate >
 bool
 equal( InputIterator1 first1, InputIterator1 last,
  InputIterator2 first2, BinaryPredicate pred );
 equal() возвращает true, если обе последовательности одинаковы в диапазоне, ограниченном парой итераторов [first,last). Если вторая последовательность содержит дополнительные элементы, они игнорируются. Чтобы убедиться в тождественности данных последовательностей, необходимо написать:
 if ( vec1.size() == vec2.size() &&
  equal( vec1.begin(), vec1.end(), vec2.begin() );
 или воспользоваться оператором равенства, определенном в классе самого контейнера: vec1 == vec2. Если второй контейнер содержит меньше элементов, чем первый, и алгоритму приходится просматривать элементы за концом контейнера, то поведение программы не определено. По умолчанию для сравнения применяется оператор равенства в классе элементов контейнера, а во втором варианте алгоритма – указанный предикат pred.
 #include
 #include
 #include
 
 class equal_and_odd{
 public:
  bool
  operator()( int val1, int val2 )
  {
  return ( val1 == val2 &&
  ( val1 == 0 || val1 % 2 ))
  ? true : false;
  }
 };
 
 int main()
 {
  int ia[] = { 0,1,1,2,3,5,8,13 };
  int ia2[] = { 0,1,1,2,3,5,8,13,21,34 };
 
  bool res;
 
  // true: обе последовательности совпадают до длины ia
  // печатается: int ia[7] равно int ia2[9]? Да.
 
  res = equal( &ia[0], &ia[7], &ia2[0] );
  cout << "int ia[7] равно int ia2[9]? "
  << ( res ? "Да" : "Нет" ) << ".\n";
 
  list< int, allocator > ilist( ia, ia+7 );
  list< int, allocator > ilist2( ia2, ia2+9 );
 
  // печатается: список ilist равен ilist2? Да.
 
  res = equal( ilist.begin(), ilist.end(), ilist2.begin() );
  cout << "список ilist равен ilist2? "
  << ( res ? "Да" : "Нет" ) << ".\n";
 
  // false: 0, 2, 8 не являются равными и нечетными
  // печатается: список ilist equal_and_odd() ilist2? Нет.
 
  res = equal( ilist.begin(), ilist.end(),
  ilist2.begin(), equal_and_odd() );
 
  cout << "список ilist equal_and_odd() ilist2? "
  << ( res ? "Да" : "Нет" ) << ".\n";
 
  return 0;
 }
  Алгоритм equal_range()
 template< class ForwardIterator, class Type >
 pair< ForwardIterator, ForwardIterator >
 equal_range( ForwardIterator first,
  ForwardIterator last, const Type &value );
 
 template< class ForwardIterator, class Type, class Compare >
 pair< ForwardIterator, ForwardIterator >
 equal_range( ForwardIterator first,
  ForwardIterator last, const Type &value,
  Compare comp );
 equal_range() возвращает пару итераторов: первый представляет значение итератора, возвращаемое алгоритмом lower_bound(), второй – алгоритмом upper_bound(). (О семантике этих алгоритмов рассказано в их описаниях.) Например, дана последовательность:
 int ia[] = {12,15,17,19,20,22,23,26,29,35,40,51};
 Обращение к equal_range() со значением 21 возвращает пару итераторов, в которой оба указывают на значение 22. Обращение же со значением 22 возвращает пару итераторов, где first указывает на 22, а second – на 23. В первом варианте при сравнении используется оператор “меньше”, определенный для типа элементов контейнера; во втором – предикат comp.
 #include
 #include
 #include
 #include
 
 /* печатается:
  последовательность элементов массива после сортировки:
  12 15 17 19 20 22 23 26 29 35 40 51
 
  результат equal_range при поиске значения 23:
  *ia_iter.first: 23 *ia_iter.second: 26
 
  результат equal_range при поиске отсутствующего значения 21:
  *ia_iter.first: 22 *ia_iter.second: 22
 
  последовательность элементов вектора после сортировки:
  51 40 35 29 26 23 22 20 19 17 15 12
 
  результат equal_range при поиске значения 26:
  *ivec_iter.first: 26 *ivec_iter.second: 23
 
  результат equal_range при поиске отсутствующего значения 21:
  *ivec_iter.first: 20 *ivec_iter.second: 20
 */
 int main()
 {
  int ia[] = { 29,23,20,22,17,15,26,51,19,12,35,40 };
  vector< int, allocator > ivec( ia, ia+12 );
  ostream_iterator< int > ofile( cout, " " );
 
  sort( &ia[0], &ia[12] );
 
  cout << "последовательность элементов массива после сортировки:\n";
  copy( ia, ia+12, ofile ); cout << "\n\n";
 
  pair< int*,int* > ia_iter;
  ia_iter = equal_range( &ia[0], &ia[12], 23 );
 
  cout << "результат equal_range при поиске значения 23:\n\t"
  << "*ia_iter.first: " << *ia_iter.first << "\t"
  << "*ia_iter.second: " << *ia_iter.second << "\n\n";
 
  ia_iter = equal_range( &ia[0], &ia[12], 21 );
 
  cout << "результат equal_range при поиске "
  << "отсутствующего значения 21:\n\t"
  << "*ia_iter.first: " << *ia_iter.first << "\t"
  << "*ia_iter.second: " << *ia_iter.second << "\n\n";
 
  sort( ivec.begin(), ivec.end(), greater() );
 
  cout << "последовательность элементов вектора после сортировки:\n";
  copy( ivec.begin(), ivec.end(), ofile ); cout << "\n\n";
 
  typedef vector< int, allocator >::iterator iter_ivec;
  pair< iter_ivec, iter_ivec > ivec_iter;
 
  ivec_iter = equal_range( ivec.begin(), ivec.end(), 26,

<< Пред.           стр. 105 (из 121)           След. >>

Список литературы по разделу