Search code examples
c++stringbstr

Reverse Find pointer to nth occurrence of a character in cstring


How to Reverse Find pointer to nth occurrence of a character in cstring/BSTR?

char * RFindNthOccurrence(char* src, char t, int n)
{
   //for i/p string src = "HI,There,you,All"
   // and t =','
   // n =2
   //returned pointer should be at ",you,All" in same unchanged string
}

I've found first and last occurrence searching, but without modifying string reverse finding nth occurrence is problem.


Solution

  • How about this?

    #include <iostream>
    
    const char * RFindNthOccurrence( const char *s, char c, size_t n )
    {
        if ( !n ) return NULL;
    
        while ( ( n -= *s == c ) && *s ) ++s;
    
        return n == 0 ? s : NULL;
    }
    
    char * RFindNthOccurrence( char *s, char c, size_t n )
    {
        if ( !n ) return NULL;
    
        while ( ( n -= *s == c ) && *s ) ++s;
    
        return n == 0 ? s : NULL;
    }
    
    int main() 
    {
        const char *s1 = "HI,There,you,All";
    
        std::cout << RFindNthOccurrence( s1, ',', 2 ) << std::endl;
    
        char s2[] = "HI,There,you,All";
    
        std::cout << RFindNthOccurrence( s2, ',', 2 ) << std::endl;
    
        return 0;
    }
    

    The program output is

    ,you,All
    ,you,All
    

    The function behaves the same way as standard C function strchr that is it finds the terminating zero character but only in case when n = 1.

    Another example

    #include <iostream>
    
    const char * RFindNthOccurrence( const char *s, char c, size_t n )
    {
        if ( !n ) return NULL;
    
        while ( ( n -= *s == c ) && *s ) ++s;
    
        return n == 0 ? s : NULL;
    }
    
    char * RFindNthOccurrence( char *s, char c, size_t n )
    {
        if ( !n ) return NULL;
    
        while ( ( n -= *s == c ) && *s ) ++s;
    
        return n == 0 ? s : NULL;
    }
    
    int main() 
    {
        const char *s = "HI,There,you,All";
        const char *p = s;
    
        for ( size_t i = 1; p = RFindNthOccurrence( s, ',', i ); ++i )
        {
            std::cout << i << ": " << p << std::endl;
        }
    
        return 0;
    }
    

    The program output is

    1: ,There,you,All
    2: ,you,All
    3: ,All
    

    The same you could do using standard C function strchr without writing a special function. For example

    #include <iostream>
    #include <cstring>
    
    int main() 
    {
        const char *s = "HI,There,you,All";
        const char *p = s;
        size_t n = 2;
    
        while ( ( p = std::strchr( p, ',' ) ) && --n ) ++p;
    
        if ( n == 0 ) std::cout << p << std::endl;
    
        return 0;
    }
    

    The program output is

    ,you,All
    

    If you need indeed the reverse search then the function can look like in this demonstrative program

    #include <iostream>
    #include <cstring>
    
    const char * RFindNthOccurrence( const char *s, char c, size_t n )
    {
        if ( !n ) return NULL;
    
        const char *p = s + std::strlen( s );
    
        while ( ( n -= *p == c ) && p != s ) --p;
    
        return n == 0 ? p : NULL;
    }
    
    int main() 
    {
        const char *s = "HI,There,you,All";
        const char *p = s;
    
        for ( size_t i = 1; p = RFindNthOccurrence( s, ',', i ); ++i )
        {
            std::cout << i << ": " << p << std::endl;
        }
    
        return 0;
    }
    

    In this case the program output is

    1: ,All
    2: ,you,All
    3: ,There,you,All