Is there a way to apply non-modifying standard library algorithms to discrete functions instead of containers?
For example, consider the following function
int sqr(int i)
{
return i*i;
}
How can I use std::find or std::lower_bound to search for the value 49, i.e. the algorithm should return 7? The easiest way would be to put the returns into a vector and apply the algorithm to the vector -- but this is obviously inefficient.
Hypothetically, you could use something like boost::iterator::counting_iterator. E.g., the following finds that 4 is the number whose square is 16:
#include <algorithm>
#include <iostream>
#include <boost/iterator/counting_iterator.hpp>
using namespace std;
int main(int, char**)
{
auto f = std::find_if(
boost::make_counting_iterator<int>(0),
boost::make_counting_iterator<int>(20),
[](int i){return i * i == 16;});
cout << std::distance(
boost::make_counting_iterator<int>(0),
f) << endl;
return 0;
}
I think that this approach is problematic in many ways. In the above, in particular, note that it searches for such numbers up to 20.
Related
The following code fails to compile, but if I remove the commented line, it compiles and runs correctly. I was only intending to use boost because C++ doesn't provide a hash function for std::unordered_set<int> by default.
#include <iostream>
#include <boost/unordered_set.hpp>
int main() {
boost::unordered_set<boost::unordered_set<int> > fam;
boost::unordered_set<int> s;
s.insert(5);
s.insert(6);
s.insert(7);
std::cout << s.size() << std::endl;
fam.insert(s); // this is the line causing the problem
return 0;
}
Edit 1:
I want to be more clear than I was in the OP. First I know that the idea of the boost::unordered_set<> is that it is implemented with a hash table, rather than a BST. I know that anything that is to be a template type to the boost::unordered_set<> needs to have a hash function and equality function provided. I also know that by default the std::unordered_set<> does not have a hash function defined which is why the following code does not compile:
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<std::unordered_set<int> > fam;
return 0;
}
However, I thought that boost provides hash functions for all their containers which is why I believed the following code does compile:
#include <iostream>
#include <boost/unordered_set.hpp>
int main() {
boost::unordered_set<boost::unordered_set<int> > fam;
return 0;
}
So now, I'm not sure why boost code just above compiles, but the code in the OP does not. Was I wrong that boost provides a hash function for all their containers? I would really like to avoid having to define a new hash function, especially when my actual intended use is to have a much more complicated data structure: boost::unordered_map<std::pair<boost::unordered_map<int, int>, boost::unordered_map<int, int> >, int>. It seems like this should be a solved problem that I shouldn't have to define myself, since IIRC python can handle sets of sets no problem.
An unordered_set (or _map) uses hashing, and requires a hash operator to be defined for its elements. There is no hash operator defined for boost::unordered_set<int>, therefore it cannot put such a type of element into your set.
You may write your own hash function for this. For example, this is a typical generic hash approach, though you may want to customize it for your particular data. If you drop this code into your example, it should work:
namespace boost {
std::size_t hash_value(boost::unordered_set<int> const& arg) {
std::size_t hashCode = 1;
for (int e : arg)
hashCode = 31 * hashCode + hash<int>{}(e);
return hashCode;
}
}
Since I am new in competitive programming so I am finding this a bit difficult. I encountered a code and I am not able to figure it out, need some help to understand it.
#include<iostream>
#include<algorithm>
using namespace std;
bool mycompare(int a ,int b){
return a>b;
}
int main(){
int a[]={5,4,3,1,2,6,7};
int n =sizeof(a)/sizeof(int);
sort(a,a+n,mycompare);
for(int i=0; i<n;i++){
cout<<a[i]<<"";
}
return 0;
}
output:
7 6 5 4 3 2 1
How does this code work more specifically what does the mycompare function do in the code?
My doubt is that why haven't we passed any arguments in the mycompare() function inside the main() function since the prototype of the function is
bool mycompare(int a, int b);
A comparison-based sorting algorithm sorts the elements solely by pair-wise comparison, i.e., if a < b holds, then a has to be placed before b.
This is a fine approach, but if you limit yourself to using <, it only allows you to sort elements in an ascending order. What if you want to have them in descending order, or any other ordering? This is where the concept of a Comparator (or a Compare callable in the context of the C++ standard) comes into play: It is a binary predicate bool compare(element a, element b) that is supposed to replace the < operator, i.e., a < b becomes compare(a, b) instead. This generalization allows you to encapsulate all types of orderings, in your question you already provided an example where the comparison uses a greater-than operator >, which gives you the aforementioned descending sorted order.
As for how this works internally in C++, the details can be rather complicated, but you can look at it as this:
mycompare without any parameters is a function pointer, i.e. a pointer to the memory address where the machine code for mycompare starts. You can do something like
auto func_pointer = mycompare;
func_pointer(1, 2); // calls mycompare(1, 2)
By giving this function pointer as a parameter to std::sort, you replace the default < comparison function by your own. The way C++ works internally gives the additional advantage that this function call can most likely be inlined, i.e., the compiler avoids the function call can be avoided by copying the code from mycompare into the std::sort invocation, which can speed up your code significantly.
std::sort takes a RandomIt (random iterator) as the first and second arguments that must satisfy the requirements of ValueSwappable and LegacyRandomAccessIterator. Instead of using a Plain-Old-Array of int, you want to use std::array which can then provide the iterators with the member functions .begin() and .end().
Using a proper container from the C++ standard template library makes sorting with std::sort trivial. You need not even provide a custom compare function to sort in descending order as std::less<int>() is provided for you (though your purpose may be to provide the compare function)
Your prototype for mycompare will work fine as is, but preferably the parameters are const type rather than just type, e.g.
bool mycompare(const int a, const int b)
{
return a > b;
}
The implementation using the array container is quite trivial. Simply declare/initialize your array a and then call std::sort (a.begin(), a.end(), mycompare); A complete working example would be:
#include <iostream>
#include <algorithm>
#include <array>
bool mycompare(const int a, const int b)
{
return a > b;
}
int main (void) {
std::array<int, 7> a = { 5, 4, 3, 1, 2, 6, 7 };
std::sort (a.begin(), a.end(), mycompare);
for (auto& i : a)
std::cout << " " << i;
std::cout << '\n';
}
Example Use/Output
$ ./bin/array_sort
7 6 5 4 3 2 1
Sorting the Plain Old Array*
If you must use a Plain-Old-Array, then you can use plain-old-pointers as your random iterrators. While not a modern C++ approach, you can handle the plain-old-array with std::sort. You can make use of the builtin std::greater<type>() for a descending sort or std::less<type>() for an ascending sort.
An implementation using pointers would simply be:
#include <iostream>
#include <algorithm>
int main (void) {
int a[] = { 5, 4, 3, 1, 2, 6, 7 };
size_t n = sizeof a / sizeof *a;
#if defined (ASCEND)
std::sort (a, a + n, std::less<int>());
#else
std::sort (a, a + n, std::greater<int>());
#endif
for (size_t i = 0; i < n; i++)
std::cout << " " << a[i];
std::cout << '\n';
}
(same output unless -DASCEND is added as a define on the commandline, and then an ascending sort will result from the use of std::less<int>())
Look things over and let me know if you have further questions.
I want to find both the minimum and maximum of a long vector. The following code works, but I need to traverse the vector twice.
I could use an old fashioned for loop, but I wonder if there is an elegant (c++11, std) way of doing it.
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char** argv) {
vector<double> C;
// code to insert values in C not shown here
const double cLower = *min_element(C.begin(), C.end());
const double cUpper = *max_element(C.begin(), C.end());
// code using cLower and cUpper
}
You mean like std::minmax_element?
auto mm = std::minmax_element(std::begin(c), std::end(c));
const double cLower = *mm.first;
const double cUpper = *mm.second;
Note this assumes the range is not empty (as does your existing solution), else the iterator dereferences are Undefined Behaviour.
Also note this is not quite the same as your solution, as max_element returns the first largest element, and minmax_element returns the last largest element. E.g.
1 2 1 2
^ ^
A B
Where A is found by your solution, and B is found by mine. (This is for reasons of stability; Alex Stepanov got the definition of max wrong in the original STL.)
I wrote a function for vector comparison.
#include <vector>
#include <iostream>
#include <algorithm>
using std::vector;
using std::cout;
bool mycomp(const vector<int>& vi_a, const vector<int>& vi_b){
for(auto x:vi_a) cout << x;
cout << '\n';
return true;
}
int main(){
vector<int> vi1{2,9,8};
vector<int> vi2{3,5,6};
vector<int> vi = min(vi1, vi2, mycomp);
for(auto x:vi) cout << x;
cout << '\n';
}
Output:
356
356
What's weird is that the output is 356, instead of 298. It seems that the two vectors are switched when calling mycomp.
p.s. I'd rather not use lambda here, because mycomp contains more than one line of code, which is more readable this way.
If you take a look at the cppreference documentation for std::min() you will see in the possible implementation that the second element is used as the first element in the comparator.
template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp)
{
return (comp(b, a)) ? b : a;
}
And when you call min() with the arguments vi2 and vi1, the second argument is passed to the comparator (which in your case is vi2), upon which the comparator returns true (implying that vi2 is the minimum of the two). While doing this the comparator also prints out 356 because that is the first element passed to the comparator according to the possible implementation above.
After that happens you take the presumably smaller of the two vectors, which is the first one passed to the comparator according to the possible implementation above (which is vi2). And you print that out. Therefore you get 356 again.
Note that the reason b is passed as the first argument to std::min is because in the case where the two compare equal the algorithm is required to return a. At the same time it is required to call the comparator only once. Combining these two requirements gives the possible implementation above.
As the function accepted by for_each take only one parameter (the element of the vector), I have to define a static int sum = 0 somewhere so that It can be accessed
after calling the for_each . I think this is awkward. Any better way to do this (still use for_each) ?
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
static int sum = 0;
void add_f(int i )
{
sum += i * i;
}
void test_using_for_each()
{
int arr[] = {1,2,3,4};
vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
for_each( a.begin(),a.end(), add_f);
cout << "sum of the square of the element is " << sum << endl;
}
In Ruby, We can do it this way:
sum = 0
[1,2,3,4].each { |i| sum += i*i} #local variable can be used in the callback function
puts sum #=> 30
Would you please show more examples how for_each is typically used in practical programming (not just print out each element)? Is it possible use for_each simulate 'programming pattern' like map and inject in Ruby (or map /fold in Haskell).
#map in ruby
>> [1,2,3,4].map {|i| i*i}
=> [1, 4, 9, 16]
#inject in ruby
[1, 4, 9, 16].inject(0) {|aac ,i| aac +=i} #=> 30
EDIT: Thank you all. I have learned so much from your replies. We have so many ways to do the same single thing in C++ , which makes it a little bit difficult to learn. But it's interesting :)
No, don't use std::accumulate() use std::inner_product(). No functor required.
#include <vector>
#include <numeric>
void main()
{
std::vector <int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
int x = std::inner_product( v1.begin(), v1.end(), v1.begin(), 0 );
}
Use std::accumulate
#include <vector>
#include <numeric>
// functor for getting sum of previous result and square of current element
template<typename T>
struct square
{
T operator()(const T& Left, const T& Right) const
{
return (Left + Right*Right);
}
};
void main()
{
std::vector <int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
int x = std::accumulate( v1.begin(), v1.end(), 0, square<int>() );
// 0 stands here for initial value to which each element is in turn combined with
// for our case must be 0.
}
You could emulate std::accumulate as in nice GMan's answer, but I believe that using std::accumulate will make your code more readable, because it was designed for such purposes. You could find more standard algorithms here.
for_each returns (a copy of) the functor that it was using. So, something like this:
#include <algorithm>
#include <vector>
#include <iostream>
template <typename T>
class square_accumulate
{
public:
square_accumulate(void) :
_sum(0)
{
}
const T& result(void) const
{
return _sum;
}
void operator()(const T& val)
{
_sum += val * val;
}
private:
T _sum;
};
int main(void)
{
int arr[] = {1,2,3,4};
std::vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
int sum = std::for_each(a.begin(), a.end(), square_accumulate<int>()).result();
std::cout << "sum of the square of the element is " << sum << std::endl;
}
As demonstrated by other answers, though, std::accumulate is the best way to go.
Don't use for_each() for this, use accumulate() from the <numeric> header:
#include <numeric>
#include <iostream>
using namespace std;
struct accum_sum_of_squares {
// x contains the sum-of-squares so far, y is the next value.
int operator()(int x, int y) const {
return x + y * y;
}
};
int main(int argc, char **argv) {
int a[] = { 4, 5, 6, 7 };
int ssq = accumulate(a, a + sizeof a / sizeof a[0], 0, accum_sum_of_squares());
cout << ssq << endl;
return 0;
}
The default behaviour of accumulate() is to sum elements, but you can provide your own function or functor as we do here, and the operation it performs need not be associative -- the 2nd argument is always the next element to be operated on. This operation is sometimes called reduce in other languages.
You could use a plain function instead of the accum_sum_of_squares functor, or for even more genericity, you could make accum_sum_of_squares a class template that accepts any numeric type.
As a general solution to such issue with STL: instead of passing a function, you can pass a functor -- for example, an instance of any class implementing operator(). This is much better than relying on global variables, since said instance can keep and update its own state! You could think of it as a kind of "compile time duck typing": generic programming does not constrain you to pass a "function" in that place, anything that "behaves like a function" (i.e., has a proper operator()) will do as well!-)
std::for_each is for doing something with each element. If you want get a result from a calculation on all the elements, there's std::accumulate. If you are wanting Haskell's map behaviour, use std::transform.
You can abuse either of these three to do the same thing as any of the others, since ultimately they are just iterating over an iterator (except for transform's form that takes two iterators as input.) The point is that for_each is not a replacement for map/fold - that should be done by transform/accumulate - although C++ doesn't natively have something that expresses the map/fold concept as well as Haskell does - but both gcc and VC++ support OpenMP which has a much better analogue in #pragma omp parallel for.
Inject in Ruby is a much closer match to calling for_each with a full-fledged functor, like GMan explained above. Lambda functions with variable capture in C++0X will make the behaviour between the two languages even more similar:
int main(void)
{
int arr[] = {1,2,3,4};
std::vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
int sum = 0;
std::for_each(a.begin(), a.end(), [&](int i) { sum += i*i;} );
std::cout << "sum of the square of the element is " << sum << std::endl;
}