почему std :: search требует передачи iters - PullRequest
5 голосов
/ 20 марта 2011

моя проблема идентична приведенной ниже теме, я изо всех сил пытаюсь понять предоставленные ответы, или, скорее, мой код не должен работать, поскольку он использует только итераторы ввода ... но мой func, кажется, работает и ведет себя идентично std:: search ..so Я в растерянности и не хочу идти дальше, не понимая должным образом ... возможно, если кто-то может предложить ввод, который нарушит мою функцию, но не std ::

From Зачем мне нужен прямой итератор для реализации моего настроенного std :: search :

Я изучаю книгу "Ускоренный C ++" из Koenig & Moo.

Упражнение 8-2 попросить меня самостоятельно реализовать некоторые шаблонизированные функции из и и указать, какой тип итератора требуется для моей реализации.

При попытке реализовать std :: search я определил,что мне нужны только «входные» итераторы.

Однако, глядя на реализацию std :: search, установленную с моим компилятором, я вижу, что они используют «прямые» итераторы, но я не могу отменитьВыясните, почему, поскольку нет необходимости писать, только читать, и входные итераторы отвечают требованию.

Может ли кто-нибудь здесь помочь мне понять это, пожалуйста?Зачем мне нужно использовать "итераторы" вперед для реализации std :: search?

Заранее спасибо.

myfunction:

template <class In> 
In search(  In begin, In end, In begin2, In end2 )
{
    In found ;                      // iter: 1st element in pattern match(in content)
    In pattern_begin = begin2 ;     // iter: 1st element in search pattern.
    int flag = 0 ;                  // flag: partial match found?

    // search content for pattern 
    while (  begin < end  ) {

        // if pattern-match fails ..reset vars
        // & continue searching remaining content/elements
        if ( *begin != *begin2 ) {

            In ret ;                     
            begin2 = pattern_begin ;
            flag = 0 ;
            begin++ ;


        } else {
            // compare next element in pattern with next element in content.
            // if: 1st element of 'pattern' is found, store iter to it's pos
            // ..then if entire pattern is found, we can ret an iter to where it starts
            if ( flag == 0 ) { 
                found = begin ;
                flag = 1 ;
            }
            // inc iters to compare next elements in partial match
            begin++ ;
            begin2++ ;
        }

        // if: iter is 1-past end of search pattern
        // then entire pattern has been found 
        // return the iter to where it starts
        if( begin2 == end2 ) {  return found ;  }

    }

    // end of content reached, no complete pattern found
    // begin should? equal an iter 1-past the end of content
    return begin ;
}

драйвер:

///* // Driver: custom::search(  b, e, b2, e2  ) 
#include <string>
#include <vector>
#include <iostream>
//#include <algorithm>
#include "library_algorithms.h"

int main() {

    // init string test
    std::string content = "fo The fox  foxu jumped  foxe foxy " ;
    std::string search_pattern = "foxy" ;

    // func test on string
    std::string::iterator ret_iter = 
    custom::search(  content.begin(), content.end(), search_pattern.begin(), search_pattern.end()  ) ;
    //std::search(  content.begin(), content.end(), search_pattern.begin(), search_pattern.end()  ) ;

    // output
    if (  ret_iter != content.end()  ) {

        std::cout << std::endl << std::endl << search_pattern << ": found at position: " << int(  ret_iter - content.begin()  ) << std::endl;

    } else { 

        std::cout << std::endl << std::endl << search_pattern << ": ...not found" << std::endl;
    }




    // Init vec test:
    // create content values in range:  10 20 30 <......> 9970 9980 9990
    std::vector<int> myvector;
    for (int i=1; i<1000; i++) myvector.push_back(i*10);

    // create pattern values to search for
    std::vector<int> pattern ;
    pattern.push_back( 3730 ) ;
    pattern.push_back( 3740 ) ;
    pattern.push_back( 3750 ) ;
    pattern.push_back( 3760 ) ;

    // test: func on vector<int>
    std::vector<int>::iterator it;
    it = custom::search (  myvector.begin(), myvector.end(), pattern.begin(), pattern.end() );

    // output
    if (it!=myvector.end())
    std::cout << std::endl << std::endl << "pattern found at position " << int(it-myvector.begin()) << std::endl;
    else
    std::cout << std::endl << std::endl << "pattern not found" << std::endl;





    return 0 ;

}

1 Ответ

11 голосов
/ 20 марта 2011

Вы неправильно поняли, что может делать входной итератор.

Вы не можете "сохранить" или скопировать входной итератор. Это позволяет вам пройти последовательность ровно один раз. Другими словами, эта строка, помимо прочего, оборвется: begin2 = pattern_begin.

Итератор ввода может представлять то, что вы не можете легко «перемотать», например, поток данных, полученных от сетевого адаптера. Итератор, указывающий на «6 элементов назад», больше не имеет смысла, потому что эти данные могут больше не быть доступными в памяти. У вас есть только текущая позиция в потоке.

Должно быть очевидно, что для правильной реализации search необходимо иметь возможность проходить части последовательности более одного раза.

...