What is the purpose of a wrapper over recursive function?
Why can't we directly call the recursive function from the main function?
I've come across some explanations saying that wrapper function helps in better parameter passing - I don't understand this.
EDIT:
Consider the example of a binary search based function that returns the index of a peak element:
int findPeakUtil(int arr[], int low,
int high, int n)
{
// Find index of middle element
int mid = low + (high - low)/2;
// Compare middle element with its neighbours (if neighbours exist)
if ((mid == 0 || arr[mid - 1] <= arr[mid]) &&
(mid == n - 1 || arr[mid + 1] <= arr[mid]))
return mid;
// If middle element is not peak and its
// left neighbour is greater than it,
// then left half must have a peak element
else if (mid > 0 && arr[mid - 1] > arr[mid])
return findPeakUtil(arr, low, (mid - 1), n);
// If middle element is not peak and its
// right neighbour is greater than it,
// then right half must have a peak element
else return findPeakUtil(arr, (mid + 1), high, n);
}
// A wrapper over recursive function findPeakUtil()
int findPeak(int arr[], int n)
{
return findPeakUtil(arr, 0, n - 1, n);
}
Why is it recommended to use the wrapper function?
A wrapper function can prepare a call of a recursive function. For example a recursive function has more parameters then initially the user supplies. Or can make a preliminary checks of the validity of arguments and tests pre-conditions.
Here is a simple example provided for the demonstrative purpose.
#include <iostream>
#include <cstring>
char * recursive_reverse( char *s, size_t n )
{
if ( n < 2 ) return s;
char c = s[0];
s[0] = s[n-1];
s[n-1] = c;
recursive_reverse( s + 1, n - 2 );
return s;
}
char * reverse( char *s )
{
return recursive_reverse( s, std::strlen( s ) );
}
int main()
{
char s[] = "Hello DEBNATH KUNDU";
std::cout << s << '\n';
std::cout << reverse( s ) << '\n';
return 0;
}
The program output is
Hello DEBNATH KUNDU
UDNUK HTANBED olleH
Another example is when a class has a non-static public member function that calls a static (private/protected) recursive member function passing to it required data members of the object of the class. So in this case the non-static member function provides the public interface and the non-static recursive function provides the implementation of the interface.
Here is one more demonstrative program.
#include <iostream>
#include <utility>
#include <cstring>
class String
{
private:
enum Size : size_t { N = 100 };
char s[N];
static void recursive_reverse( char *s, size_t n )
{
if ( not ( n < 2 ) )
{
std::swap( s[0], s[n-1] );
recursive_reverse( s + 1, n - 2 );
}
}
public:
explicit String( const char *s )
{
strncpy( this->s, s, N );
this->s[N-1] = '\0';
}
void reverse() { recursive_reverse( s, std::strlen( s ) ); }
friend std::ostream & operator <<( std::ostream &os, const String &s )
{
return os << s.s;
}
};
int main()
{
String s( "Hello DEBNATH KUNDU" );
std::cout << s << '\n';
s.reverse();
std::cout << s << '\n';
return 0;
}
Its output is the same as shown above.
However it does not mean that a wrapper function is always required.
Related
Can somebody please help me get this code working? The Reverse method is to take a char array parameter, and return a reversed array. Then I want to print it out in main
#include <iostream>
#include <iomanip>
using namespace std;
char[] Reverse(char ch[]) {
char arr[sizeof(ch)];
for (int i=0; i< sizeof(ch); i++){
arr[i] = ch[sizeof(ch) -i -1];
}
return arr;
}
int main() {
char ch1[] = {'a', 'b', 'c'};
char ch2[] = Reverse(ch1);
cout << ch2[0] << endl;
return 0;
}
For starters this function declaration
char[] Reverse(char ch[]);
is incorrect. Functions may not have an array return type.
You could declare the function like
char * Reverse(char ch[]);
but as your function does not deal with strings then in this case it is more logical consistent to declare your function like
void Reverse( char ch[], size_t n );
As the function parameter of the array type is adjusted by the compiler to pointer to the element type of the array like
void Reverse( char *ch, size_t n );
then within the function the parameter ch is a pointer. As a result this expression sizeof( ch ) used within the function yields the size of pointer that depending on the used system is equal to either 4 or 8. so it is why I specified the second parameter of the function because you need explicitly to pass the array size if the array is not passed to the function by reference.
Within the function you are trying to return pointer to the first element of a local array
char arr[sizeof(ch)];
//...
return arr;
that makes the returned pointer invalid because the array will not be alive after exiting the function.
As the first parameter of the function is declared without the qualifier const then it means that the function needs to reverse the original array instead of making a reversed copy of the original array.
Pay attention to that this statement in main
cout << ch2[0] << endl;
does not make great sense. It outputs only the first element of the array.
Taking all this into account the function can be defined the following way
#include <iostream>
#include <utility>
void Reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
std::swap( s[i], s[n-i-1] );
}
}
int main()
{
char s[] = { 'a', 'b', 'c' };
std::cout.write( s, sizeof( s ) ) << '\n';
Reverse( s, sizeof( s ) );
std::cout.write( s, sizeof( s ) ) << '\n';
return 0;
}
The program output is
abc
cba
An alternative approach is to write a template function. In this case the second parameter is not required.
Here you are.
#include <iostream>
#include <utility>
template <size_t N>
void Reverse( char ( &s )[N] )
{
for ( size_t i = 0; i < N / 2; i++ )
{
std::swap( s[i], s[N-i-1] );
}
}
int main()
{
char s[] = { 'a', 'b', 'c' };
std::cout.write(s, sizeof( s ) ) << '\n';
Reverse( s );
std::cout.write(s, sizeof( s ) ) << '\n';
return 0;
}
If you want to write a function that reverses a string stored in a character array then the function declaration can look like
char * Reverse( char s[] );
Here is one more demonstrative program.
#include <iostream>
#include <utility>
#include <cstring>
char * Reverse( char *s )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n-i-1] );
}
return s;
}
int main()
{
char s[] = { 'a', 'b', 'c', '\0' };
std::cout << s << '\n';
std::cout << Reverse( s ) << '\n';
return 0;
}
The program output will be the same as it is shown above that is
abc
cba
Pay attention to that there is standard algorithm std::revrese that you could use for your original array
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
char s[] = { 'a', 'b', 'c' };
std::cout.write( s, sizeof( s ) ) << '\n';
std::reverse( std::begin( s ), std::end( s ) );
std::cout.write( s, sizeof( s ) ) << '\n';
return 0;
}
If the array contains a string then in general case a call of the algorithm will look the following way
#include <iostream>
#include <algorithm>
#include <cstring>
int main()
{
char s[] = { 'a', 'b', 'c', '\0' };
std::cout << s << '\n';
std::reverse( s, s + std::strlen( s ) );
std::cout << s << '\n';
return 0;
}
I got a class Matrix with a member std::list<Element> listMatrix;. Element is a a class with 3 int members line, column, value. I save in the list, elements of a matrix that are not 0 by saving the line, column and the value of the respectively element. I want to overload the operator [][] so I can do something like Matrix a; a[2][3] = 5;. I know you can't overload [][] directly.
Do overload Element& operator()(int, int) (and the const variant) so you can write
matrix(2, 3) = 5;
If you absolutely need the [2][3] syntax, you'd need to define a proxy class so matrix[2] return a proxy value and proxy[3] return the desired reference. But it comes with a lot of problems. The basic idea would be:
class naive_matrix_2x2
{
int data[4];
struct proxy
{
naive_matrix_2x2& matrix;
int x;
int& operator[](int y) { return matrix.data[x*2+y]; }
};
public:
proxy operator[](int x) { return {*this, x}; }
};
Full demo: https://coliru.stacked-crooked.com/a/fd053610e56692f6
The list is not a suitable container for using the subscript operator because it has no direct access to its elements without moving an iterator through the list.
So the operator will be inefficient.
It is better to use the standard container std::vector that already has the subscript operator.
Nevertheless answering your question the operator can be defined the following way. You can add to the operators an exception then an index will point outside the list.
#include <iostream>
#include <list>
struct A
{
int x, y, z;
int & operator []( size_t n )
{
return n == 0 ? x : n == 1 ? y : z;
}
const int & operator []( size_t n ) const
{
return n == 0 ? x : n == 1 ? y : z;
}
};
struct B
{
std::list<A> lst;
A & operator []( size_t n )
{
auto it = std::begin( lst );
for ( ; n; n-- ) std::advance( it, 1 );
return *it;
}
const A & operator []( size_t n ) const
{
auto it = std::begin( lst );
for ( ; n; n-- ) std::advance( it, 1 );
return *it;
}
};
int main()
{
B b = { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } } };
std::cout << b[0][0] << '\n';
std::cout << b[0][1] << '\n';
std::cout << b[0][2] << '\n';
b[2][1] += 20;
std::cout << b[2][1] << '\n';
}
The program output is
1
2
3
28
The code below executes 4x faster, if near "REPLACING WITH .." line, the functor compare_swaps() will be replaced with direct reference to my_intcmp(). Apparently the indirect use is not being inlined. Why?
inline bool my_intcmp( const int & a, const int & b ) {
return a < b;
}
template <class T, class compare>
void insertion_sort_3( T* first, T* last, compare compare_swaps ) {
// Count is 1?
if( 1 == (last - first) )
return;
for( T* it = first + 1; it != last; it ++ ) {
T val = *it;
T* jt;
for( jt = it; jt != first; jt -- ) {
// REPLACING WITH if( my_intcmp(val, *(jt - 1) ) gives 4x speedup, WHY?
if( compare_swaps(val, *(jt - 1)) ) {
*jt = *(jt - 1);
} else {
break;
}
}
*jt = val;
}
}
#define SIZE 100000
#define COUNT 4
int main() {
int myarr[ SIZE ];
srand( time(NULL) );
int n = COUNT;
while( n-- ) {
for( int i = 0; i < SIZE; i ++ )
myarr[ i ] = rand() % 20000;
insertion_sort_3( myarr, myarr + SIZE, my_intcmp );
}
return 0;
}
The compiler sees a function pointer which he can't really determine as not changing. I have seen this a couple of times before. The fix to the problem is to use a simple wrapper struct:
struct my_intcmp_wrapper
{
bool operator()(int v0, int v1) const {
return my_intcmp(v0, v1);
}
};
Specifically for build-in types you probably want to pass the objects by value rather than by reference. For inlined functions it probably doesn't make much of a difference but if the function isn't inlined it generally makes the situation worse.
My question is similar to this, but I have two strings (as char *) and the task is to replace strnicmp function (avaible only for MS VC) with something like boost::iequals.
Note strnicmp is not stricmp - it only compares first n characters.
Is there any solution simplier than this:
void foo(const char *s1, const char *s2)
{
...
std::string str1 = s1;
std::string str2 = s2;
int n = 7;
if (boost::iequals(str1.substr(0, n), str2)) {
...
}
}
If it's really necessary, write your own function:
bool mystrnicmp(char const* s1, char const* s2, int n){
for(int i=0; i < n; ++i){
unsigned char c1 = static_cast<unsigned char>(s1[i]);
unsigned char c2 = static_cast<unsigned char>(s2[i]);
if(tolower(c1) != tolower(c2))
return false;
if(c1 == '\0' || c2 == '\0')
break;
}
return true;
}
For case insensitivity, you need a custom comparison function
(or functor):
struct EqIgnoreCase
{
bool operator()( char lhs, char rhs ) const
{
return ::tolower( static_cast<unsigned char>( lhs ) )
== ::tolower( static_cast<unsigned char>( rhs ) );
}
};
If I understand correctly, you're checking for a prefix. The
simplest way to do this is:
bool
isPrefix( std::string const& s1, std::string const& s2 )
{
return s1.size() <= s2.size()
&& std::equals( s1.begin(), s1.end(), s2.begin(), EqIgnoreCase() );
}
(Note the check of the sizes. s1 can't be a prefix of s2 if
it it longer than s2. And of course, std::equals will
encounter undefined behavior if called with s1 longer than
s2.)
For a function defined in terms of C strings (character pointers) going "up" to STL strings seems horribly inefficient, but maybe that's totally premature thinking on my part.
I would consider a straight C solution "simpler", but again that depends on one's perspective.
#include <ctype.h>
void foo(const char *s1, const char *s2)
{
size_t i, n = 7;
for(i = 0; i < n; i++)
{
if(tolower(s1[i]) != tolower(s2[i]))
return;
if(s[i] == '\0' && s2[i] == '\0')
break;
}
/* Strings are equal, do the work. */
...
}
This assumes that if both strings end before the length of the prefix has been exhausted, it's a match.
Of course the above assumes ASCII strings where tolower() makes sense.
I suggest to write the function yourselfs, like this:
bool strnicmp2(const char *s, const char *t, size_t n) {
while (n > 0 && *s && *t && tolower(*s) == tolower(*t)) {
++s;
++t;
--n;
}
return n == 0 || !*s || !*t;
}
something like this ought to work..
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
#include <algorithm>
struct isequal
{
bool operator()(int l, int r) const
{
return std::tolower(l) == std::tolower(r);
}
};
bool istrncmp(const char* s1, const char* s2, size_t n)
{
size_t ls1 = std::strlen(s1);
size_t ls2 = std::strlen(s2);
// this is strict, but you can change
if (ls1 < n || ls2 < n)
return false;
return std::equal(s1, s1 + n, s2, isequal());
}
int main(void)
{
std::cout << istrncmp("fooB", "fooA", 3) << std::endl;
std::cout << istrncmp("fooB", "fooA", 5) << std::endl;
std::cout << istrncmp("fooB", "f1oA", 3) << std::endl;
return 0;
}
I don't know if this counts as simpler or not, but it has fewer lines and speed should be pretty good.
#include <boost/iterator/transform_iterator.hpp>
#include <algorithm>
#include <cctype>
bool equal_insensitive_n( char const *a, char const *b, size_t n ) {
n = std::min( n, std::min( ::strlen( a ) + 1, ::strlen( b ) + 1 ) );
#define tilc(S) boost::make_transform_iterator( (S), ::tolower )
return std::equals( tilc(a), tilc(a) + n, tilc(b) );
#undef tilc
}
I need to find an element position in an std::vector to use it for referencing an element in another vector:
int find( const vector<type>& where, int searchParameter )
{
for( int i = 0; i < where.size(); i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return -1;
}
// caller:
const int position = find( firstVector, parameter );
if( position != -1 ) {
doAction( secondVector[position] );
}
however vector::size() returns size_t which corresponds to an unsigned integral type that can't directly store -1. How do I signal that the element is not found in a vector when using size_t instead of int as an index?
Take a look at the answers provided for this question: Invalid value for size_t?. Also you can use std::find_if with std::distance to get the index.
std::vector<type>::iterator iter = std::find_if(vec.begin(), vec.end(), comparisonFunc);
size_t index = std::distance(vec.begin(), iter);
if(index == vec.size())
{
//invalid
}
First of all, do you really need to store indices like this? Have you looked into std::map, enabling you to store key => value pairs?
Secondly, if you used iterators instead, you would be able to return std::vector.end() to indicate an invalid result. To convert an iterator to an index you simply use
size_t i = it - myvector.begin();
You could use std::numeric_limits<size_t>::max() for elements that was not found. It is a valid value, but it is impossible to create container with such max index. If std::vector has size equal to std::numeric_limits<size_t>::max(), then maximum allowed index will be (std::numeric_limits<size_t>::max()-1), since elements counted from 0.
std::vector has random-access iterators. You can do pointer arithmetic with them. In particular, this my_vec.begin() + my_vec.size() == my_vec.end() always holds. So you could do
const vector<type>::const_iterator pos = std::find_if( firstVector.begin()
, firstVector.end()
, some_predicate(parameter) );
if( position != firstVector.end() ) {
const vector<type>::size_type idx = pos-firstVector.begin();
doAction( secondVector[idx] );
}
As an alternative, there's always std::numeric_limits<vector<type>::size_type>::max() to be used as an invalid value.
In this case, it is safe to cast away the unsigned portion unless your vector can get REALLY big.
I would pull out the where.size() to a local variable since it won't change during the call. Something like this:
int find( const vector<type>& where, int searchParameter ){
int size = static_cast<int>(where.size());
for( int i = 0; i < size; i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return -1;
}
If a vector has N elements, there are N+1 possible answers for find. std::find and std::find_if return an iterator to the found element OR end() if no element is found. To change the code as little as possible, your find function should return the equivalent position:
size_t find( const vector<type>& where, int searchParameter )
{
for( size_t i = 0; i < where.size(); i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return where.size();
}
// caller:
const int position = find( firstVector, parameter );
if( position != secondVector.size() ) {
doAction( secondVector[position] );
}
I would still use std::find_if, though.
Something like this, I think. find_if_counted.hpp:
#ifndef FIND_IF_COUNTED_HPP
#define FIND_IF_COUNTED_HPP
#include <algorithm>
namespace find_if_counted_impl
{
template <typename Func>
struct func_counter
{
explicit func_counter(Func& func, unsigned &count) :
_func(func),
_count(count)
{
}
template <typename T>
bool operator()(const T& t)
{
++_count;
return _func(t);
}
private:
Func& _func;
unsigned& _count;
};
}
// generic find_if_counted,
// returns the index of the found element, otherwise returns find_if_not_found
const size_t find_if_not_found = static_cast<size_t>(-1);
template <typename InputIterator, typename Func>
size_t find_if_counted(InputIterator start, InputIterator finish, Func func)
{
unsigned count = 0;
find_if_counted_impl::func_counter<Func> f(func, count);
InputIterator result = find_if(start, finish, f);
if (result == finish)
{
return find_if_not_found;
}
else
{
return count - 1;
}
}
#endif
Example:
#include "find_if_counted.hpp"
#include <cstdlib>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
int rand_number(void)
{
return rand() % 20;
}
bool is_even(int i)
{
return i % 2 == 0;
}
int main(void)
{
container vec1(10);
container vec2(10);
std::generate(vec1.begin(), vec1.end(), rand_number);
std::generate(vec2.begin(), vec2.end(), rand_number);
unsigned index = find_if_counted(vec1.begin(), vec1.end(), is_even);
if (index == find_if_not_found)
{
std::cout << "vec1 has no even numbers." << std::endl;
}
else
{
std::cout << "vec1 had an even number at index: " << index <<
" vec2's corresponding number is: " << vec2[index] << std::endl;
}
}
Though I feel like I'm doing something silly... :X Any corrections are welcome, of course.
You probably should not use your own function here.
Use find() from STL.
Example:
list L;
L.push_back(3);
L.push_back(1);
L.push_back(7);
list::iterator result = find(L.begin(), L.end(), 7);
assert(result == L.end() || *result == 7);
Take a vector of integer and a key (that we find in vector )....Now we are traversing the vector until found the key value or last index(otherwise).....If we found key then print the position , otherwise print "-1".
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int>str;
int flag,temp key, ,len,num;
flag=0;
cin>>len;
for(int i=1; i<=len; i++)
{
cin>>key;
v.push_back(key);
}
cin>>num;
for(int i=1; i<=len; i++)
{
if(str[i]==num)
{
flag++;
temp=i-1;
break;
}
}
if(flag!=0) cout<<temp<<endl;
else cout<<"-1"<<endl;
str.clear();
return 0;
}
Get rid of the notion of vector entirely
template< typename IT, typename VT>
int index_of(IT begin, IT end, const VT& val)
{
int index = 0;
for (; begin != end; ++begin)
{
if (*begin == val) return index;
}
return -1;
}
This will allow you more flexibility and let you use constructs like
int squid[] = {5,2,7,4,1,6,3,0};
int sponge[] = {4,2,4,2,4,6,2,6};
int squidlen = sizeof(squid)/sizeof(squid[0]);
int position = index_of(&squid[0], &squid[squidlen], 3);
if (position >= 0) { std::cout << sponge[position] << std::endl; }
You could also search any other container sequentially as well.