2011-03-20 22 views
5

mi problema es idéntico al siguiente subproceso, me cuesta entender las respuestas dadas, o mejor dicho, mi código no debería funcionar ya que solo usa iteradores de entrada ... pero mi func Parece que funciona y se comporta de forma idéntica a std :: search ..so que estoy perdido y detesta moverme sin entenderlo correctamente ... tal vez si alguien puede sugerir una entrada que rompa mi función, pero no el std ::por qué std :: search necesita reenviar iters

de Why do I need a Forward Iterator to implement my customized std::search:

estoy estudiando el libro "Accelerated C++" de Koenig & MOO.

Ejercicio 8-2 me pregunta para implementar en mi poseen algunas funciones a plantillas de < algoritmo numérico > y < >, y para especificar qué tipo de iterador que hace mi aplicación requiere.

Al intentar implementar std :: search, determiné que solo necesito "entrada" iteradores.

Sin embargo, mirando a la puesta en práctica de std :: Buscar instalado mi compilador, puedo ver que utilizan iteradores "hacia adelante", pero no puede entender por qué, porque no hay necesidad de escribir, solo para leer, y los iteradores de entrada cumplen el requisito.

¿Alguien aquí me puede ayudar a entender esto, por favor? ¿Por qué tendría que usar los iteradores "forward" para implementar std :: search?

Gracias de antemano.

mifuncion:

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

conductor:

///* // 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 ; 

} 

Respuesta

11

Usted ha entendido mal lo que un iterador de entrada se puede hacer.

No puede "guardar" o copiar un iterador de entrada. Le permite recorrer la secuencia exactamente una vez. En otras palabras, esta línea, entre otras, se romperá: begin2 = pattern_begin.

Un iterador de entrada puede representar algo que no se puede "rebobinar" fácilmente, como, por ejemplo, la secuencia de datos recibidos de un adaptador de red. Un iterador que apunta a "6 elementos atrás" ya no es significativo, porque es posible que esos datos ya no estén disponibles en la memoria. Solo tiene la posición actual en la transmisión.

Debería ser obvio que para implementar search correctamente, necesita poder recorrer partes de la secuencia más de una vez.

+0

parece obvio ... pero mi función parece bastante feliz de recorrer la secuencia de búsqueda más de una vez ... cuando encuentra coincidencias parciales ... se restablece cuando la coincidencia de patrón se rompe ... hasta que encuentra una coincidencia completa ... – tuk

+0

sry luchando con forum abit .... He agregado el controlador a mi op que muestra myfunc buscando una coincidencia completa ..al final de múltiples coincidencias parciales/incompletas ... tal vez si puede sugerir una entrada que rompa mi func .. Puedo avanzar paso a paso para comprender mejor – tuk

+2

@tuk: sí pero está llamando a la función con iteradores de acceso aleatorio (cadena y vectores iteradores). Intente llamarlo con 'std :: input_iterator' por ejemplo. Por supuesto, si su código depende de características que se encuentran en los iteradores directos, y lo llama con algo * más fuerte * que un iterador directo, funcionará bien. ;) Necesitarás pasar un iterador de entrada a tu función para ver si funciona con los iteradores de entrada. :) – jalf