Advance C++ : Non-Modifying STL Algorithms

Discussion in 'C++' started by BiplabKamal, Aug 3, 2016.

  1. BiplabKamal

    BiplabKamal Member

    Joined:
    Dec 30, 2015
    Messages:
    37
    Likes Received:
    7
    Trophy Points:
    8
    Occupation:
    Software Engineer
    Location:
    Kolkata
    C++ STL algorithms are template functions which operate on sequence of elements. A large number of such functions are provided by the STL to do operations like searching and sorting. Most of the algorithms operates on some kind of iterators. So it works for any container which supports the required iterator for a particular algorithm function. Algorithms operate directly on values through iterator, so it does not anyway changes the structures of the container and does not change size or storage allocation of the container. Algorithm functions in STL are in the header <algorithm> and under the namespace std. Algorithm functions which does not modify the sequence of elements they operate on are discussed here.

    All the algorithm functions take iterators as inputs to identify the range of elements and most of them also take function objects (or functors) as input which operate on the elements. Most of the time these function objects are predicates (binary or unary) whose return type is bool. Predicates cab be a function pointer, functor or a lamada expression. You can use STL functors wherever applicable. A range is specified by two iterators, one pointing to the first element of the range and the other pointing to the next to the last element of the range. That means the range contains the element pointing by the first iterator but not the last iterator.

    To know more about function object read the topics for C++ Closures: Functors, Lamdas and std::function and C++ STL Functors

    std::all_of()



    This function detects if all the elements in the given range satisfy a condition.

    Equivalent Implementation:
    Code:
    template <class Iterator_Input, class UnaryPredicate>
    bool all_of(Iterator_Input begin, Iterator_Input end, UnaryPredicate fnobj)
    {
        while (begin != end) {
            if (!fnobj(*begin)) return false;
            ++begin;
        }
        return true;
    };
    
    The predicate fnobj is called passing the value of each element in the range defined by begin and end iterators and returns true if fnobj returns true for all the elements or the range is empty, false otherwise. The function object takes one argument and returns bool value. It does not modify the argument.

    The iterators should meet the criteria of input iterator.

    It throws exception if the predicate fnobj throws or any operation on the iterators throws.

    Example:
    Code:
    #include <algorithm>   
    #include <array> 
    #include <iostream>
    struct IsOdd : public std::unary_function<int, bool> {
        bool operator() (int val)
        {
            return (val % 2 != 0);
        }
    };
    bool IsNonZero(int n)
    {
        return (n != 0);
    }
    int main()
    {
        std::array<int, 10> myarray{ -1,-2,-3,-4,-5,6,7,8,9,10 };
        std::cout << "The numbers are:" << std::endl;
        for (int i : myarray)
            std::cout << i << " ";
        std::cout << std::endl;
        // Passing a lamda expression as the unary predicate
        if (all_of(myarray.begin(), myarray.end(), [](int i) {return i>0;}))
            std::cout << "All the numbers are positive numbers" << std::endl;
        else
            std::cout << "All the numbers are not positive numbers" << std::endl;
    
        // Passing a functor as the unary predicate
        if (all_of(myarray.begin(), myarray.end(), IsOdd()))
            std::cout << "All the numbers are odd numbers" << std::endl;
        else
            std::cout << "All the numbers are not odd numbers" << std::endl;
    
        // Passing a function pointer as the unary predicate
        if (all_of(myarray.begin(), myarray.end(), IsNonZero))
            std::cout << "All the numbers are non-zero numbers" << std::endl;
        else
            std::cout << "All the numbers are not non-zero numbers" << std::endl;
        return 0;
    }
    
    Output:
    Code:
    The numbers are:
    -1 -2 -3 -4 -5 6 7 8 9 10
    All the numbers are not positive numbers
    All the numbers are not odd numbers
    All the numbers are non-zero numbers
    

    std::any_of():



    This function detects if any of the elements in the given range satisfy a condition.

    Equivalent Implementation:
    Code:
    template <class Iterator_Input, class UnaryPredicate>
    bool any_of(Iterator_Input begin, Iterator_Input end, UnaryPredicate fnobj)
    {
        while (begin != end) {
            if (fnobj(*begin)) return true;
            ++begin;
        }
        return false;
    };
    
    The predicate fnobj is called for each element’s value starting at the beginning of the range defined by begin and end iterators and stops as long as it finds an element for which the fnobj returns true or reach the end of the range. It returns true if fnobj returns true for any of the elements, false otherwise. The function object takes one argument and returns bool value. It does not modify the argument.

    The iterators should meet the criteria of input iterator.

    It throws exception if the predicate fnobj throws or any operation on the iterators throws.

    Example:
    Code:
    #include <algorithm>   
    #include <array> 
    #include <iostream>
    struct IsOdd : public std::unary_function<int, bool> {
        bool operator() (int val)
        {
            return (val % 2 != 0);
        }
    };
    bool IsZero(int n)
    {
        return (n == 0);
    }
    int main()
    {
        std::array<int, 10> myarray{ -10,-20,-30,-40,-50,-60,-70,-80,-90,0 };
        std::cout << "The numbers are:" << std::endl;
        for (int i : myarray)
            std::cout << i << " ";
        std::cout << std::endl;
        // Passing a lamda expression as the unary predicate
        if (any_of(myarray.begin(), myarray.end(), [](int i) {return i>0;}))
            std::cout << "At least on number is positive number in the list" << std::endl;
        else
            std::cout << "There is no positive number in the list" << std::endl;
    
        // Passing a functor as the unary predicate
        if (any_of(myarray.begin(), myarray.end(), IsOdd()))
            std::cout << "At least one number is odd in the list" << std::endl;
        else
            std::cout << "There is no odd number in the list" << std::endl;
    
        // Passing a function pointer as the unary predicate
        if (any_of(myarray.begin(), myarray.end(), IsZero))
            std::cout << "At least one number is zero in the list" << std::endl;
        else
            std::cout << "There is no zero value in the list" << std::endl;
        return 0;
    }
    
    Output:
    Code:
    The numbers are:
    -10 -20 -30 -40 -50 -60 -70 -80 -90 0
    There is no positive number in the list
    There is no odd number in the list
    At least one number is zero in the list
    

    std::none_of():



    This function detects if none of the elements in the given range satisfy a condition.
    Code:
    Equivalent Implementation:
    template <class Iterator_Input, class UnaryPredicate>
    bool none_of(Iterator_Input begin, Iterator_Input end, UnaryPredicate fnobj)
    {
        while (begin != end) {
            if (fnobj(*begin)) return false;
            ++begin;
        }
        return true;
    };
    
    The predicate fnobj is called for every element’s value in the range defined by begin and end iterators and returns true if fnobj returns false for all the elements or the range is empty, false otherwise. The function object takes one argument and returns bool value. It does not modify the argument.

    The iterators should meet the criteria of input iterator.

    It throws exception if the predicate fnobj throws or any operation on the iterators throws.

    Example:
    Code:
    #include <algorithm>   
    #include <array> 
    #include <iostream>
    struct IsOdd : public std::unary_function<int, bool> {
        bool operator() (int val)
        {
            return (val % 2 != 0);
        }
    };
    bool IsZero(int n)
    {
        return (n == 0);
    }
    int main()
    {
        std::array<int, 10> myarray{ -10,-20,-30,-40,-50,-60,-70,-80,-90,11 };
        std::cout << "The numbers are:" << std::endl;
        for (int i : myarray)
            std::cout << i << " ";
        std::cout << std::endl;
        // Passing a lamda expression as the unary predicate
        if (none_of(myarray.begin(), myarray.end(), [](int i) {return i>0;}))
            std::cout << "No positive number in the list" << std::endl;
        else
            std::cout << "At least one positive number in the list" << std::endl;
    
        // Passing a functor as the unary predicate
        if (none_of(myarray.begin(), myarray.end(), IsOdd()))
            std::cout << "No odd number in the list" << std::endl;
        else
            std::cout << "At leaset one odd number in the list" << std::endl;
    
        // Passing a function pointer as the unary predicate
        if (none_of(myarray.begin(), myarray.end(), IsZero))
            std::cout << "No number is zero in the list" << std::endl;
        else
            std::cout << "At least one number is zero in the list" << std::endl;
        return 0;
    }
    
    Output:
    Code:
    The numbers are:
    -10 -20 -30 -40 -50 -60 -70 -80 -90 11
    At least one positive number in the list
    At leaset one odd number in the list
    No number is zero in the list
    

    std::for_each():



    Performs some operation on each of the elements in the given range

    Equivalent Implementation:
    Code:
    template<class InputIterator, class Function>
    Function for_each(InputIterator begin, InputIterator end, Function ftor )
    {
        while (begin != end) {
            ftor(*begin);
            ++begin;
        }
        return std::move(ftor);
    }
    
    Apply function object ftor to each of the elements and return the same function object.

    The predicate ftor is called for every element in the range defined by begin and end iterators and returns the function object back. The function object’s function operator takes one argument. It’s return value is ignored. The function object should be move constructable.

    The iterators should meet the criteria of input iterator.

    It throws exception if the predicate ftor throws or any operation on the iterators throws.

    Example:

    Code:
    #include <algorithm>  
    #include<functional>
    #include <array> 
    #include <iostream>
    struct Add : public std::unary_function<int, bool> {
        int sum{ 0 };
        int operator() (int val)
        {
            sum += val;
            return sum;
        }
    };
    int Negate(int& element)
    {
        element=element* -1;
        return element;
    }
    int main()
    {
        std::array<int, 10> myarray{ -10,-20,-30,-40,-50,-60,-70,-80,-90,11 };
        std::cout << "The numbers are:" << std::endl;
        // Passing a lamda expression as the unary predicate
        for_each(myarray.begin(), myarray.end(), [](int val) {std::cout << val << " ";});
        std::cout << std::endl;
        // Passing a functor as the unary predicate
        Add result = for_each(myarray.begin(), myarray.end(), Add());
        std::cout << "The sum of the numbers is: " << result.sum<<std::endl;
       
        // Passing a function pointer as the unary predicate
        for_each(myarray.begin(), myarray.end(), Negate);
        std::cout << "Negation of the numbers are: " << std::endl;
        for_each(myarray.begin(), myarray.end(), [](int val) {std::cout << val << " ";});
        std::cout << std::endl;
        return 0;
    }
    
    Output
    Code:
    The numbers are:
    -10 -20 -30 -40 -50 -60 -70 -80 -90 11
    The sum of the numbers is: -439
    Negation of the numbers are:
    10 20 30 40 50 60 70 80 90 -11
    

    std::find():



    Finds a value in the given range

    Equivalent Implementation:
    Code:
    template<class InputIterator, class T>
    InputIterator find(InputIterator begin, InputIterator end, const T& val)
    {
        while (begin != end) {
            if (*begin == val) return begin;
            ++begin;
        }
        return end;
    }
    
    Returns an iterator to the first element which compares equal to val. If no such element is found it returns the iterator end. The function uses operator == to compare each element with the val. So value should be of same type of the elements or comparable with the type of elements.

    Example:
    Code:
    #include <algorithm>  
    #include<functional>
    #include <array> 
    #include <iostream>
    
    int main()
    {
        std::array<int, 10> myarray{ -10,-20,-30,-40,-50,-60,-70,-80,-90,11 };
        std::cout << "The numbers are:" << std::endl;
        std::for_each(myarray.begin(), myarray.end(), [](const int& val) {std::cout << val << " ";});
        std::cout << std::endl;
        int i{ -20 }, j{ 30 };
        if (std::find(myarray.begin(), myarray.end(), i) != myarray.end())
            std::cout << i << " is present in the list" << std::endl;
        else
            std::cout << i << " is not present in the list" << std::endl;
    
        if (std::find(myarray.begin(), myarray.end(), j) != myarray.end())
            std::cout << j << " is present in the list" << std::endl;
        else
            std::cout << j << " is not present in the list" << std::endl;
            return 0;
    }
    
    Output:
    Code:
    The numbers are:
    -10 -20 -30 -40 -50 -60 -70 -80 -90 11
    -20 is present in the list
    30 is not present in the list
    

    std::find_if():



    Finds a value in the given range which satisfy a condition

    Equivalent Implementation:
    Code:
    template<class InputIterator, class UnaryPredicate>
    InputIterator find_if(InputIterator begin, InputIterator end, UnaryPredicate ftor)
    {
        while (begin != end) {
            if (ftor(*begin))
                return begin;
            ++begin;
        }
        return end;
    }
    
    Returns an iterator to the first element for which ftor returns true. If no such element is found it returns the iterator end. The function calls ftor for each element until it it returns true or the end of the range is reached.

    The predicate should take the value of type of the elements of the range. The predicate should not modify the element.

    Example:

    Code:
    #include <algorithm>  
    #include<functional>
    #include <array> 
    #include <iostream>
    class Positive
    {
    public:
        bool operator() (const int& n)
        {
            return (n > 0);
        }
    };
    
    bool IsNonZero(const int& n)
    {
        return n != 0;
    }
    
    int main()
    {
        std::array<int, 10> myarray{ 0,-10,-20,-30,40,-50,-60,-80,-90,11 };
        std::cout << "The numbers are:" << std::endl;
        std::for_each(myarray.begin(), myarray.end(), [](const int& val) {std::cout << val << " ";});
        std::cout << std::endl;
       
        // Using lamda expression as unary predicate
        auto odditr = std::find_if(myarray.begin(), myarray.end(), [](const int& val) {return val % 2;});
        if(odditr == myarray.end())
            std::cout <<"No odd number in the list" << std::endl;
        else
            std::cout << "The first odd number in the list is: "<<*odditr << std::endl;
    
        // Using functor as unary predicate
        auto positr = std::find_if(myarray.begin(), myarray.end(), Positive());
        if (positr == myarray.end())
            std::cout << "No positive number in the list" << std::endl;
        else
            std::cout << "The first positive number in the list is: " << *positr << std::endl;
    
        // Using function pointer as unary predicate
        auto nonzeroitr = std::find_if(myarray.begin(), myarray.end(), IsNonZero);
        if (nonzeroitr == myarray.end())
            std::cout << "No non zero number in the list" << std::endl;
        else
            std::cout << "The first non zero number in the list is: " << *nonzeroitr << std::endl;
                return 0;
    }
    
    Output:
    Code:
    The numbers are:
    0 -10 -20 -30 40 -50 -60 -80 -90 11
    The first odd number in the list is: 11
    The first positive number in the list is: 40
    The first non zero number in the list is: -10
    

    std::find_if_not():



    Finds an element in the given range if it does not satisfy a given criteria

    Equivalent Implementation:
    Code:
    template<class InputIterator, class UnaryPredicate>
    InputIterator find_if_not(InputIterator begin, InputIterator end, UnaryPredicate ftor)
    {
        while (begin != end) {
            if (!ftor(*begin))
                return begin;
            ++begin;
        }
        return end;
    }
    
    Returns an iterator to the first element for which ftor returns false. If no such element is found it returns the iterator end. The function calls ftor for each element until it it returns false or the end of the range is reached.

    The predicate should take the value of type of the elements of the range. The predicate should not modify the element.

    Exampe:
    Code:
    #include <algorithm>  
    #include <array> 
    #include <iostream>
    class Positive
    {
    public:
        bool operator() (const int& n)
        {
            return (n > 0);
        }
    };
    
    int main()
    {
        std::array<int, 10> myarray{ 13,-10,-20,-30,40,-50,-60,-80,-90,11 };
        std::cout << "The numbers are:" << std::endl;
        std::for_each(myarray.begin(), myarray.end(), [](const int& val) {std::cout << val << " ";});
        std::cout << std::endl;
       
        // Using lamda expression as unary predicate
        auto evenitr = std::find_if_not(myarray.begin(), myarray.end(), [](const int& val) {return val % 2;});
        if(evenitr == myarray.end())
            std::cout <<"No even number in the list" << std::endl;
        else
            std::cout << "The first even number in the list is: "<<*evenitr << std::endl;
    
        // Using functor as unary predicate
        auto nonpositr = std::find_if_not(myarray.begin(), myarray.end(), Positive());
        if (nonpositr == myarray.end())
            std::cout << "No non positive number in the list" << std::endl;
        else
            std::cout << "The first non positive number in the list is: " << *nonpositr << std::endl;
    
        return 0;
    }
    
    Code:
    The numbers are:
    13 -10 -20 -30 40 -50 -60 -80 -90 11
    The first even number in the list is: -10
    The first non positive number in the list is: -10
    

    std::find_end():



    Finds last sub sequence in the given range

    Declarations:

    Version1:
    Code:
    template <class ForwardIterator1, class ForwardIterator2>
       ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);
    
    Version2:
    Code:
    template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
       ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2,
                                  BinaryPredicate pred);
    
    Look for the sub range defined by first[first2,last2) in the range defined by [first1,last1] for it’s last occurrence and returns an iterator to its first element, or last1 if no occurrences are found. The elements are compared with operator == for the version 1 and the pred in the version2

    std::find_first_of():



    Finds an element from a range int another given range

    Declarations:
    Code:
    Version1:
    template <class InputIterator, class ForwardIterator>
       InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2);
    
    Version2:
    Code:
    template <class InputIterator, class ForwardIterator, class BinaryPredicate>
       InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2,
                                       BinaryPredicate pred);
    
    Find the first element in the range defined by first1 and last 1 which matches any of the elements in the range defined by first2 and last2. The elements are compared with operator == for the version 1 and the pred in the version2

    std:: adjacent_find():



    Finds equal adjacent elements int the given rnge

    Declarations:

    Version1:
    Code:
    template <class ForwardIterator>
       ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last);
    
    Version2:
    Code:
    template <class ForwardIterator, class BinaryPredicate>
       ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
    
    Searches the range for the first occurrence of two consecutive elements which matches. The matching is compared by operator == or the pred. It returns the iterator pointed to the first element of such pair if it finds, else returns the iterator last

    Example:

    Code:
    #include <iostream>    
    #include <algorithm> 
    #include<functional>
    #include <list>
    #include<vector>
    using namespace std;
    int main()
    {
        vector<int> v{ 11,12,13,1000 };
        list<int> mylist = { -1,-2,-3,-4,-5,6,7,8,9,10 };
    
        cout << "The numbers in the list are:" << endl;
        std::for_each(mylist.begin(), mylist.end(), [](int item) {cout << item << " ";});
        cout << endl;
       
        cout << "The numbers in the sub range are:" << endl;
        std::for_each(v.begin(), v.end(), [](int item) {cout << item << " ";});
        cout << endl;
    
        // std::find_end- Without using Predicate
        cout << endl << "Searching for last subrange for equality" << endl;
        auto itr = std::find_end(mylist.begin(), mylist.end(),v.begin(),v.end());
        if (itr != mylist.end())
            std::cout <<" The sub range is present in the list "<<endl;
        else
            std::cout << "The sub range is not present in the list" << endl;
    
        // std::find_end- Using Predicate
        cout << endl << "Searching for last subrange with compare function" << endl;
        itr = std::find_end(mylist.begin(), mylist.end(), v.begin(), v.end(), [](int val1, int val2) {return -val1 == val2;});
        if (itr != mylist.end())
            std::cout << " The sub range with negation is present in the list " << endl;
        else
            std::cout << "The sub range with negation is not present in the list" << endl;
    
        // std::find_first_of- Without using Predicate
        cout << endl << "Searching for any element from the subrange for equality" << endl;
        itr = std::find_first_of(mylist.begin(), mylist.end(), v.begin(), v.end());
        if (itr != mylist.end())
            std::cout << "At least one element in the sub range is present in the list" << endl;
        else
            std::cout << "No element int the sub range is present in the list" << endl;
    
        // std::find_first_of-Using Predicate
        cout << endl << "Searching for any element from the subrange with comparison" << endl;
        itr = std::find_first_of(mylist.begin(), mylist.end(), v.begin(), v.end(),greater<int>());
        if (itr != mylist.end())
            std::cout << "At least one element in the sub range is less than some element in the list" << endl;
        else
            std::cout << "No element int the sub range is less than any element in the list" << endl;
    
        // std::adjacent_find-Without using Predicate
        cout << endl << "Searching for any adjacent two equal elements in the list" << endl;
        itr = std::adjacent_find(mylist.begin(), mylist.end());
        if (itr != mylist.end())
            std::cout <<  "Adjacent sequence found in the list" << endl;
        else
            std::cout << "Adjacent sequence not found in the list" << endl;
    
        // std::adjacent_find-Using Predicate
        cout << endl << "Searching for any adjacent two matching elements in the list with compare function" << endl;
        itr = std::adjacent_find(mylist.begin(), mylist.end(), [](int val1, int val2) {return val1 + 1 == val2;});
        if (itr != mylist.end())
            std::cout << "Adjacent incremental sequence found in the list" << endl;
        else
            std::cout << "Adjacent incremental sequence not found in the list" << endl;
    
        return 0;
    }
    
    Code:
    The numbers in the list are:
    -1 -2 -3 -4 -5 6 7 8 9 10
    The numbers in the sub range are:
    11 12 13 1000
    
    Searching for last subrange for equality
    The sub range is not present in the list
    
    Searching for last subrange with compare function
    The sub range with negation is not present in the list
    
    Searching for any element from the subrange for equality
    No element int the sub range is present in the list
    
    Searching for any element from the subrange with comparison
    No element int the sub range is less than any element in the list
    
    Searching for any adjacent two equal elements in the list
    Adjacent sequence not found in the list
    
    Searching for any adjacent two matching elements in the list with compare function
    Adjacent incremental sequence found in the list
    

    std:: count():



    Find the number of occurrences of a given value in a range

    Declarations:

    Version1:
    Code:
    template <class InputIterator, class T>
      typename iterator_traits<InputIterator>::difference_type
        count (InputIterator first, InputIterator last, const T& val);
    
    Returns the number of elements which are equal to val.

    std:: count_if():

    Find the number of elements in a range who satisfy a condition

    Declarations:

    Version1:
    Code:
    template <class InputIterator, class UnaryPredicate>
      typename iterator_traits<InputIterator>::difference_type
        count_if (InputIterator first, InputIterator last, UnaryPredicate pred);
    
    Returns the number of elements for which the pred returns true.

    Example:
    Code:
    
    #include <iostream>    
    #include <algorithm> 
    #include <set>
    using namespace std;
    int main()
    {
        //set<int> s{ 3,6,8,1,9,7,4,9,10,100 };
        multiset<int> mylist = { -1,-2,-3,-4,-5,6,7,8,9,10,6 };
    
        cout << "The numbers in the list are:" << endl;
        std::for_each(mylist.begin(), mylist.end(), [](int item) {cout << item << " ";});
        cout << endl;
           
        // std::count
        auto count = std::count(mylist.begin(), mylist.end(), 6);
        cout << "Number of times 6 appears in the list: " << count<<endl;
    
        //std::count_if
        count = std::count_if(mylist.begin(), mylist.end(), [](int i) {return i % 2;});
        cout << "Number of odd elements in the list: " << count<<endl;
    
        return 0;
    }
    
    Code:
    The numbers in the list are:
    -5 -4 -3 -2 -1 6 6 7 8 9 10
    Number of times 6 appears in the list: 2
    Number of odd elements in the list: 5
    

    std:: mismatch():



    Find the first mismatching element in two ranges

    Declarations:

    Version1:
    Code:
    template <class InputIterator1, class InputIterator2>
      pair<InputIterator1, InputIterator2>
        mismatch (InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2);
    
    Version2:
    Code:
    template <class InputIterator1, class InputIterator2, class BinaryPredicate>
      pair<InputIterator1, InputIterator2>
        mismatch (InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, BinaryPredicate pred);
    
    
    Compares the elements of the first range defined by first1 and last1 with the elements in the second range starting by first 2 and returns the iterators pointing to the first elements in the two ranges who defers. It returns a pair of iterator whose first item points to the first mismatching element of the first range and the second item points to the first mismatching element of the second range. The elements are compared using operator == or pred (in the second template). If all the elements match then it returns a pair whose first element is last1 and the second element is the iterator for the second range which points to the relative position from the first2 equal to the difference of first1 and last1.

    std:: equal():



    Detects if two ranges are equal

    Declarations:

    Version1:
    Code:
    template <class InputIterator1, class InputIterator2>
      bool equal (InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2);
    
    Version2:
    Code:
    template <class InputIterator1, class InputIterator2, class BinaryPredicate>
      bool equal (InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, BinaryPredicate pred);
    
    Compares the elements of the first range defined by first1 and last1 with the elements in the second range starting by first 2 and returns true if all the elements match, false otherwise. The elements are compared using operator == or pred (in the second template).

    std:: is_permutation():



    Detects if one range is the permutation of another range

    Declarations:

    Version1:
    Code:
    template <class ForwardIterator1, class ForwardIterator2>
       bool is_permutation (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2);
    
    Version2:
    Code:
    template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
       bool is_permutation (ForwardIterator1 first1, ForwardIterator1 last1,
                       ForwardIterator2 first2, BinaryPredicate pred);
    
    
    Compares the elements of the first range defined by first1 and last1 with the elements in the second range starting by first 2 and returns true if all the elements match even in a different order, false otherwise. The elements are compared using operator == or pred (in the second template).

    Example:
    Code:
    
    #include <iostream>    
    #include <algorithm> 
    #include <forward_list>
    using namespace std;
    int main()
    {
        forward_list<int> mylist1 = { -1,-2,-3,-4,-5,6,7,8,9,10,6 };
        forward_list<int> mylist2 = { -1,-2,-3,-4,-5,5,7,8,9,10,6 };
        forward_list<int> mylist3 = { -1,-2,7,-4,-5,6,-3,8,9,10,6 };
    
        cout << "The numbers in the list 1 are:" << endl;
        std::for_each(mylist1.begin(), mylist1.end(), [](int item) {cout << item << " ";});
        cout << endl;
        cout << "The numbers in the list 2 are:" << endl;
        std::for_each(mylist2.begin(), mylist2.end(), [](int item) {cout << item << " ";});
        cout << endl;
        cout << "The numbers in the list 3 are:" << endl;
        std::for_each(mylist3.begin(), mylist3.end(), [](int item) {cout << item << " ";});
        cout << endl;
       
        auto pairitr = std::mismatch(mylist1.begin(), mylist1.end(), mylist2.begin());
        if (pairitr.first != mylist1.end())
            cout << "First mismatch in list 1 and list 2 is: " << *(pairitr.first) << " and " << *(pairitr.second) << endl;
        else
            cout << "No mismatch in list 1 and list 2"<< endl;
    
        if (std::equal(mylist1.begin(), mylist1.end(), mylist3.begin()))
            cout << "The list 1 and list 3 are equal" << endl;
        else
            cout << "The list 1 and list 3 are not equal" << endl;
    
        if (std::is_permutation(mylist1.begin(), mylist1.end(), mylist3.begin()))
            cout << "The list 1 is permutation of list 3" << endl;
        else
            cout << "The list 1 is not permutation of list 3" << endl;
    
        return 0;
    }
    
    Code:
    The numbers in the list 1 are:
    -1 -2 -3 -4 -5 6 7 8 9 10 6
    The numbers in the list 2 are:
    -1 -2 -3 -4 -5 5 7 8 9 10 6
    The numbers in the list 3 are:
    -1 -2 7 -4 -5 6 -3 8 9 10 6
    First mismatch in list 1 and list 2 is: 6 and 5
    The list 1 and list 3 are not equal
    The list 1 is permutation of list 3
    

    std:: search():



    Searches a range of element in another range

    Declarations:

    Version1:
    Code:
    template <class ForwardIterator1, class ForwardIterator2>
       ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                                ForwardIterator2 first2, ForwardIterator2 last2);
    
    Version2:
    Code:
    template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
       ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                                ForwardIterator2 first2, ForwardIterator2 last2,
                                BinaryPredicate pred);
    
    Searches the range defined by first1 and last1 for the first occurrence of the sub range defined by first2 and last2. It return the iterator pointing to the first element of the matching sub range if found, last1 otherwise. The elements are compared using operator == or pred (in the second template).

    std:: search_n():



    Searches the sequence of elements for a consecutive number of elements equal to a value or meeting some condition

    Declarations:

    Version 1:
    Code:
    template <class ForwardIterator, class Size, class T>
       ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
                                 Size count, const T& val);
    
    Version 2:
    Code:
    template <class ForwardIterator, class Size, class T, class BinaryPredicate>
       ForwardIterator search_n ( ForwardIterator first, ForwardIterator last,
                                  Size count, const T& val, BinaryPredicate pred );
    
    Searches the range defined by first and last for a sequence of count elements each equal to val or for which the pred returns true. It returns the iterator pointing to the first element of such sequence if found, false otherwise. The elements are compared using operator == or pred (in the second template).
    Code:
    #include <iostream>    
    #include <algorithm> 
    #include <forward_list>
    using namespace std;
    int main()
    {
        forward_list<int> mylist1 = { -1,-2,-3,-4,-5,6,7,8,9,10,6, 6,6 };
        forward_list<int> mylist2 = { -5,6,7,8,9,10,6 };
       
    
        cout << "The numbers in the list 1 are:" << endl;
        std::for_each(mylist1.begin(), mylist1.end(), [](int item) {cout << item << " ";});
        cout << endl;
        cout << "The numbers in the list 2 are:" << endl;
        std::for_each(mylist2.begin(), mylist2.end(), [](int item) {cout << item << " ";});
        cout << endl;
        auto itrfound = std::search(mylist1.begin(), mylist1.end(), mylist2.begin(),mylist2.end());
        if (itrfound != mylist1.end())
            cout << "First match of list 2 in list 1 starts: " << *(itrfound) << endl;
        else
            cout << "No match in list 1 and list 2"<< endl;
    
        auto itr = (std::search_n(mylist1.begin(), mylist1.end(), 3, 6));
        if(itr !=mylist1.end())
            cout << "The list 1 have a sequence of three 6" << endl;
        else
            cout << "The list 1 does not have a sequence of three 6" << endl;
        return 0;
    }
    
    Code:
    The numbers in the list 1 are:
    -1 -2 -3 -4 -5 6 7 8 9 10 6 6 6
    The numbers in the list 2 are:
    -5 6 7 8 9 10 6
    First match of list 2 in list 1 starts: -5
    The list 1 have a sequence of three 6
    
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice