Поиск элементов. Поиск последнего подинтервала

   
На этом шаге мы рассмотрим алгоритмы, выполняющие обратный поиск.

   
Ниже представлены алгоритмы, осуществляющие обратный поиск:

  ForwardIterator
  find_end (ForwardIterator beg, ForwardIterator end, 
            ForwardIterator searchBeg, ForwardIterator searchEnd)
  ForwardIterator
  find_end (ForwardIterator beg, ForwardIterator end,
            ForwardIterator searchBeg, ForwardIterator searchEnd,
            BinaryPredicate op)

   
Обе формы возвращают позицию первого элемента в последнем подинтервале интервала [beg,end),
совпадающем с искомым интервалом [searchBeg,searchEnd).

   
В первой форме элементы найденного подинтервала должны быть равны элементам искомого интервала.

   
Во второй форме вызов бинарного предиката op(elem,searсhElem) для соответствующих элементов искомого
интервала и подинтервала должен возвращать true.

   
Если подходящий элемент не найден, обе формы возвращают end.

   
Предикат ор не должен изменять свое состояние во время вызова и передаваемые аргументы.

   
Эти алгоритмы не входили в исходную версию STL. К сожалению, им было присвоено имя find_end()
вместо search_end(), что было бы гораздо логичнее, поскольку алгоритм поиска первого подинтервала
называется search().

   
Сложность линейная (не более numberOfElements*numberofSearchElements сравнений или вызовов ор соответственно).

   
Следующий пример показывает, как найти последнее вхождение серии элементов внутри другой последовательности
(сравните с примером использовании алгоритма search() на 273 шаге):

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iterator>
#include "algostuff.hpp"

#include <conio.h> //необходимо для getch()

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
using namespace std;

std::string ToRus(const std::string &in)
{
  char *buff = new char [in.length()+1];
  CharToOem(in.c_str(),buff);
  std::string out(buff);
  delete [] buff;
  return out;
}


int main()
{
  deque<int> coll;
  list<int> subcoll;

  INSERT_ELEMENTS(coll,1,7);
  INSERT_ELEMENTS(coll,1,7);

  INSERT_ELEMENTS(subcoll,3,6);

  PRINT_ELEMENTS(coll,   "Последовательность:\n");
  PRINT_ELEMENTS(subcoll,"Подпоследовательность:\n");

  // Поиск последнего вхождения subcoll в coll
  deque<int>::iterator pos;
  pos = find_end (coll.begin(), coll.end(),         // Интервал
                  subcoll.begin(), subcoll.end());  // Подинтервал

  // Цикл повторяется до тех пор, пока внутри coll
  // успешно находится очередное вхождение подинтервала
  deque<int>::iterator end(coll.end());
  while (pos != end) { 
      // Вывод позиции первого элемента
      cout << ToRus("Очередная подпоследовательность начинается с элемента ")
           << distance(coll.begin(),pos) + 1
           << "." << endl;

      // Поиск следующего вхождения subcoll
      end = pos;
      pos = find_end (coll.begin(), end,               // Интервал
                      subcoll.begin(), subcoll.end()); // Подинтервал
  }


  getch();
  return 0;
}

//---------------------------------------------------------------------------

Текст этого примера можно взять 274 шаге - алгоритм find_end() применяется аналогичным образом.

   
На следующем шаге мы рассмотрим поиск первого из нескольких возможных значений.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий