/// Returns the position of the 'Nth' occurrence of 'find' within 'str'.
/// Note that 1==find_Nth( "aaa", 2, "aa" ) [2nd "aa"]
/// - http://stackoverflow.com/questions/17023302/
size_t find_Nth(
const std::string & str , // where to work
unsigned N , // N'th ocurrence
const std::string & find // what to 'find'
) {
if ( 0==N ) { return std::string::npos; }
size_t pos,from=0;
unsigned i=0;
while ( i<N ) {
pos=str.find(find,from);
if ( std::string::npos == pos ) { break; }
from = pos + 1; // from = pos + find.size();
++i;
}
return pos;
/**
It would be more efficient to use a variation of KMP to
benefit from the failure function.
- Algorithm inspired by James Kanze.
- http://stackoverflow.com/questions/20406744/
*/
}
int main() {
{
// 0123456789.123456789.123
assert( 3 == find_Nth( "My gorila ate the banana", 1 , "gorila") );
assert( 18 == find_Nth( "My gorila ate the banana", 1 , "banana") );
// 0123456789.123456789.123
assert( 3 == find_Nth( "My banana ate the banana", 1 , "banana") );
assert( 18 == find_Nth( "My banana ate the banana", 2 , "banana") );
assert( std::string::npos == find_Nth( "My banana ate the banana", 3 , "banana") );
assert( std::string::npos == find_Nth( "My banana ate the banana", 3 , "gorila") );
}
assert( 1==find_Nth( "aaa", 2, "aa" ) );
assert( 0==find_Nth( "aaa", 1, "aa" ) );
{
std::string str;
// 01234567
str = "aaaaaaaa"; assert( 8==str.size() );
assert( find_Nth( str, 0 , "aa") == std::string::npos );
assert( find_Nth( str, 1 , "aa") == 0 );
assert( find_Nth( str, 2 , "aa") == 1 );
assert( find_Nth( str, 3 , "aa") == 2 );
assert( find_Nth( str, 4 , "aa") == 3 );
assert( find_Nth( str, 5 , "aa") == 4 );
assert( find_Nth( str, 6 , "aa") == 5 );
assert( find_Nth( str, 7 , "aa") == 6 );
assert( find_Nth( str, 8 , "aa") == std::string::npos );
assert( find_Nth( str, 9 , "aa") == std::string::npos );
}
}