my issue is identical to the thread below, I'm struggling to understand the answers given, or rather my code shouldn't work as it only uses input iterators ..but my func appears to work and behave identically to std::search ..so I'm at a loss and loathe to move on without understanding properly ...maybe if someone can suggest an input that will break my function but not the std::
From Why do I need a Forward Iterator to implement my customized std::search :
I am studying the book "Accelerated C++" from Koenig & Moo.
Exercise 8-2 ask me to implement on my own some templatized functions from <algorithm> and <numeric>, and to specify what kind of iterator does my implementation require.
When trying to implement std::search, I determined that I need only "input" iterators.
However, looking at the implementation of std::search installed with my compiler, I can see that they use "forward" iterators, but I cannot understand why, because there is no need to write, only to read, and input iterators meet the requirement.
Can anybody here help me to understand this, please? Why would I need to use "forward" iterators to implement std::search?
Thanks in advance.
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:
///* // 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 ;
}
Forward iterator use only increments operator (++) to move through all the elements of a container. Therefore, we can say that the forward iterator can only move forward.
A Forward Iterator is an iterator that corresponds to the usual intuitive notion of a linear sequence of values. It is possible to use Forward Iterators (unlike Input Iterators and Output Iterators) in multipass algorithms.
Generally, like this: struct vec{ iterator begin() ; const_iterator begin() const; };
An iterator is an object that can iterate over elements in a C++ Standard Library container and provide access to individual elements.
You've misunderstood what an input iterator can do.
You can't "save" or copy an input iterator. It allows you to traverse the sequence exactly once. In other words, this line, among others, will break: begin2 = pattern_begin
.
An input iterator may represents something that you can't readily "rewind", like, say, the stream of data received from a network adapter. An iterator pointing to "6 elements ago" is no longer meaningful, because that data may no longer be available in memory. You only have the current position in the stream.
It should be obvious that in order to implement search
correctly, you need to be able to traverse parts of the sequence more than once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With