The usefulness of unary and binary negators is easily understandable.
Example with unary negator (not1):
class Even
{
public:
bool operator() (const int& x) const { return x % 2 == 0; }
typedef int argument_type;
};
int values[] = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
int even = count_if(values, values + 9, Even());
int odd = count_if(values, values + 9, not1(Even())); // <= unary negator
cout << "We have " << even << " even elements in the array.\n";
cout << "We have " << odd << " odd elements in the array.\n";
Output:
We have 4 even elements in the array.
We have 5 odd elements in the array.
Example with binary negator (not2):
int values[] = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
// original array
for (int i : values)
cout << i << " ";
cout << "\n";
// array in ascending order
sort(values, values + 9, less<int>());
for (int i : values)
cout << i << " ";
cout << "\n";
// array in descending order
sort(values, values + 9, not2(less<int>())); // <= binary negator
for (int i : values)
cout << i << " ";
cout << "\n\n";
Output:
9 1 8 2 7 3 6 4 5
1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1
What about n-ary negators (not3, not4, not5 ... notn) ?
Let's assume that I need to count the number of elements that are not between two numbers (lower bound limit and upper bound limit) in a collection (maybe an array).
.
int elems_betweem = count_if(values, values + n, not3(bind(Between<int>(), _1, lowerValue, upperValue)));
.
How do I write the not3 negator?
Even more, do we have a generic not as a replacer of not1 and not2 in the same way as bind vs bind1st and bind2nd ?
Thank you
Since C++17 std::not_fn will be available:
auto between = [](int value, int lowerValue, int upperValue) {
return lowerValue < value && value < upperValue;
};
int elems_between = std::count_if(std::cbegin(values), std::cend(values),
std::bind(std::not_fn(between), std::placeholders::_1, lowerValue, upperValue));
wandbox example
How do I write the not3 negator?
A C++03 compliant example:
template<class Pred>
class ternary_predicate {
Pred pred;
public:
ternary_predicate(Pred pred): pred(pred){}
template<class A, class B, class C>
bool
operator()(A const& a, B const& b, C const& c) const {
return !pred(a, b, c);
}
};
template<class Pred>
ternary_predicate<Pred>
not3(Pred pred) {
return ternary_predicate<Pred>(pred);
}
Even more, do we have a generic not as a replacer of not1 and not2 in the same way as bind vs bind1st and bind2nd ?
We will, once C++17 is official. It is proposed to introduce std::not_fn as a replacement for std::not1 and std::not2 which will then be deprecated.
If you feel impatient, it's should not be difficult to implement yourself in C++14:
template<class Pred>
auto
not_fn(Pred&& pred) {
return [pred=std::forward<Pred>(pred)](auto&&... args){
return !pred(std::forward<decltype(args)>(args)...);
};
}
You can write your own std::not_fn as long as it's not available:
template <typename T>
struct not_func
{
template <typename...Args>
constexpr bool operator()(const Args&...args) const { return !T{}(args...); }
};
Example usage:
int main()
{
bool a1 = std::less<int>{}(1, 2);
bool a2 = not_func<std::less<int>>{}(1, 2);
bool b1 = Even{}(1);
bool b2 = not_func<Even>{}(1);
std::cout
<< "a1 = " << (a1 ? "true" : "false") << "\n"
<< "a2 = " << (a2 ? "true" : "false") << "\n"
<< "b1 = " << (b1 ? "true" : "false") << "\n"
<< "b2 = " << (b2 ? "true" : "false") << "\n";
}
[On Coliru]
[On Godbolt]
I haven't tested all possible variants so this might still be buggy.
Related
I'm taking an Intro to Programming class and a good chunk of the material is drilled into our heads through myProgrammingLab. I'm having a little trouble with the concept of Recursion... It's sort of been hit or miss for me. This particular problem has me stumped. When I submit my code, it offers me
CTest1.cpp: In function 'bool isPalindrome(int*, int)':
CTest1.cpp:9: error: invalid conversion from 'int' to 'int*'
CTest1.cpp:9: error: initializing argument 1 of 'bool isPalindrome(int*, int)'"
as advice, which I can assure you is not very helpful. Lol
I think my main problem is when I get to the actual recursion. I'm aware that something's off, but.. If you could just point me in the right direction, I would very much appreciate it.
A 'array palindrome' is an array which, when its elements are reversed, remains the same (i.e., the elements of the array are same when scanned forward or backward)
Write a recursive, bool-valued function, isPalindrome, that accepts an integer -valued array , and the number of elements and returns whether the array is a palindrome.
An array is a palindrome if: the array is empty (0 elements ) or contains only one element (which therefore is the same when reversed), or the first and last elements of the array are the same, and the rest of the array (i.e., the second through next-to-last elements ) form a palindrome.
My code so far:
bool isPalindrome(int arr[], int n)
{
if (n == 0 || n == 1)
{
return true;
}
else if (arr[n-1] == isPalindrome(arr[((n-1) - n) +1 ], n))
{
return true;
}
else
{
return false;
}
}
Recursion mostly has three main components:
a stopping condition (when you reach an array size small enough to be a guaranteed palindrome (0 or 1)),
a computation step (e.g. to compare the first and last item of the array and determine whether it makes sense to continue) and
a data subset selection for the nested recursion call (e.g. an array of size n - 2, excluding the first and last characters, which we already compared and found “palindrome-worthy”).
The three components in code:
bool isPalindrome(int arr[], size_t n) {
return n < 2 || (
arr[0] == arr[n - 1] &&
isPalindrome(arr + 1, n - 2));
}
Of course you may want to test the function a bit (and do not forget to run it under valgrind as well):
#include <iostream>
int main() {
std::cout << isPalindrome((int[0]){}, 0) << std::endl;
std::cout << isPalindrome((int[1]){1}, 1) << std::endl;
std::cout << isPalindrome((int[2]){1, 1}, 2) << std::endl;
std::cout << isPalindrome((int[2]){2, 1}, 2) << std::endl;
std::cout << isPalindrome((int[2]){1, 2}, 2) << std::endl;
std::cout << isPalindrome((int[3]){1, 2, 1}, 3) << std::endl;
std::cout << isPalindrome((int[3]){2, 2, 2}, 3) << std::endl;
std::cout << isPalindrome((int[3]){2, 2, 1}, 3) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 1, 2}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 2, 1}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 3, 2}, 4) << std::endl;
std::cout << isPalindrome((int[4]){2, 3, 2, 1}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 3, 3, 1}, 4) << std::endl;
}
As a side note, this^^^ deadly struggle with arrays suggests that a different data type would be a much better choice. For example, std::string or std::vector can be initialized way easier, should be passed by reference and, as a bonus, STL containers carry size information with them. Additionally, you can use std::string_view for substrings and std::span for “subvectors” in your recursion, without copying the container over and over on each recursion level.
Here’s an example with std::string_view and three different implementations (one with recursion and two without recursion):
#include <iostream>
#include <string_view>
bool isPalindrome1(const std::string_view s) {
return s.size() < 2 || (
s[0] == s[s.size() - 1] &&
isPalindrome1(s.substr(1, s.size() - 2)));
}
bool isPalindrome2(const std::string_view s) {
const size_t end = s.size() / 2;
for (size_t i = 0; i < end; ++i)
if (s[i] != s[s.size() - i - 1])
return false;
return true;
}
bool isPalindrome3(const std::string_view s) {
auto b = s.begin();
const auto end = b + s.size() / 2;
auto e = s.rbegin();
for (; b < end; ++b, ++e)
if (*b != *e) return false;
return true;
}
int main() {
for (auto isPalindrome : {isPalindrome1,
isPalindrome2,
isPalindrome3}) {
std::cout << isPalindrome("") << std::endl;
std::cout << isPalindrome("a") << std::endl;
std::cout << isPalindrome("ab") << std::endl;
std::cout << isPalindrome("aa") << std::endl;
std::cout << isPalindrome("abc") << std::endl;
std::cout << isPalindrome("aba") << std::endl;
std::cout << isPalindrome("baab") << std::endl;
std::cout << isPalindrome("baba") << std::endl;
}
}
isPalindrome does not accept an int as a first argument. It accepts only an array, by doing this: arr[((n-1) - n) +1] you are feeeding it an int instead if an array of ints. This ((n-1) - n) +1 will evaluate to a “position” in the array, eg: arr[0] being the first element, your case an int.
I'd like some suggestions for the most terse and 'functional' way to gather pairs of successive elements from a vector (1st and 2nd, 3rd and 4th, etc.) using modern C++. Assume the vector is of arbitrary but even length. For the examples I'm pulling together, I'm summing the elements of each pair but that's not the main problem. I should add I'll use STL only, no Boost.
In Python I can zip them into 2-tuples via an iterator with
s = range(1,11)
print([(x + y) for x,y in zip(*[iter(s)] * 2)])
In Perl 5 I can peel off pairs with
use List::Util qw/pairs sum/;
use feature 'say';
#s = 1 .. 10;
say sum #$_ foreach (pairs #s);
In Perl 6 I can shove them two at a time into a block with
my #s = 1 .. 10;
for #s -> $x, $y { say $x + $y; }
and in R I can wrap the vector into a 2-column array and sum the rows with
s <- 1:10
print(apply(matrix(s, ncol=2, byrow=TRUE), 1, sum))
I am not fluent in C++ and my solution uses for(;;). That feels too much like C.
#include <iostream>
#include <vector>
#include <numeric> // std::iota
int main() {
std::vector<int> s(10);
std::iota(s.begin(), s.end(), 1);
for (auto p = s.cbegin(); p != s.cend(); p += 2)
std::cout << (*p + *(p + 1)) << std::endl;
}
The output of course should be some variant of
3
7
11
15
19
Using range-v3:
for (auto v : view::iota(1, 11) | view::chunk(2)) {
std::cout << v[0] + v[1] << '\n';
}
Note that chunk(2) doesn't give you a compile-time-fixed size view, so you can't do:
for (auto [x,y] : view::iota(1, 11) | view::chunk(2)) { ... }
Without using range-v3 I was able to do this with either a function or a lambda template. I'll show the lambda version here.
#include <iostream>
#include <string>
#include <vector>
template<typename T>
auto lambda = [](const std::vector<T>& values, std::vector<T>& results) {
std::vector<T> temp1, temp2;
for ( std::size_t i = 0; i < values.size(); i++ ) {
if ( i & 1 ) temp2.push_back(values[i]); // odd index
else temp1.push_back(values[i]); // even index
}
for ( std::size_t i = 0; i < values.size() / 2; i++ )
results.push_back(temp[i] + temp[2]);
};
int main() {
std::vector<int> values{ 1,2,3,4,5,6 };
for (auto i : values)
std::cout << i << " ";
std::cout << '\n';
std::vector<int> results;
lambda<int>(values, results);
for (auto i : results)
std::cout << i << " ";
std::cout << '\n';
std::vector<float> values2{ 1.1f, 2.2f, 3.3f, 4.4f };
for (auto f : values2)
std::cout << f << " ";
std::cout << '\n';
std::vector<float> results2;
lambda<float>(values2, results2);
for (auto f : results2)
std::cout << f << " ";
std::cout << '\n';
std::vector<char> values3{ 'a', 'd' };
for (auto c : values3)
std::cout << c << " ";
std::cout << '\n';
std::vector<char> results3;
lambda<char>(values3, results3);
for (auto c : results3)
std::cout << c << " ";
std::cout << '\n';
std::vector<std::string> values4{ "Hello", " ", "World", "!" };
for (auto s : values4)
std::cout << s;
std::cout << '\n';
std::vector<std::string> results4;
lambda<std::string>(values4, results4);
for (auto s : results4)
std::cout << s;
std::cout << '\n';
return EXIT_SUCCESS;
}
Output
1 2 3 4 5 6
3 7 11
1.1 2.2 3.3 4.4
3.3 7.7
a d
┼
Hello World!
Hello World!
At the risk of sounding like I'm trying to be clever or annoying, I say this is the answer:
print(sums(successive_pairs(range(1,11))));
Now, of course, those aren't built-in functions, so you would have to define them, but I don't think that is a bad thing. The code clearly expresses what you want in a functional style. Also, the responsibility of each of those functions is well separated, easily testable, and reusable. It isn't necessary to use a lot of tricky specialized syntax to write code in a functional style.
I am working on a code in c++ that calulates the eigen vectors of a matrix using the Eigen library. I need only the first column and only the real values of the eigen vector. Is there a way to copy these values to the std::vector data type? Can someone help me with this?
I saw this Converting Eigen::MatrixXf to 2D std::vector post. But I need only the specific values. Moreover, I am not sure what is the type that eigenvector() function returns. In the documentation, it is said as complex Eigen::Matrix type.
This is an example code.
#include<iostream>
#include<Eigen/Eigenvalues>
#include<vector>
using namespace std;
struct eigen
{
float a, b, c;
};
int main()
{
vector<Eigen::Matrix3f> A(1);
A[0] << 1, 2, 3, 2, 4, 5, 3, 5, 6;
Eigen::EigenSolver<Eigen::Matrix3f> handle(A[0]);
cout << "The matrix of eigenvectors, V, is: " << endl << handle.eigenvectors() << endl << endl;
cout << "The real part of first column is : " << endl <<
handle.eigenvectors().col(0).real() << endl << endl;
return 0;
}
The output of the above code is
The matrix of eigenvectors, V, is:
(0.327985,0) (-0.736977,0) (-0.591009,0)
(0.591009,0) (-0.327985,0) (0.736976,0)
(0.736976,0) (0.591009,0) (-0.327985,0)
The real part of the first column is :
0.327985
0.591009
0.736976
I need to copy the values of handle.eigenvectors().col(0).real() to std::vector<eigen>
Map is the answer:
Vector3f::Map(&v[0].a) = handle.eigenvectors().col(0).real();
You can add a constructor and/or an assignment operator to eigen that copies the values.
struct eigen
{
eigen() = default;
template <typename InputIterator, typename = std::iterator_traits<InputIterator>::value_type>
eigen(InputIterator first) : a(*first++), b(*first++), c(*first++) {}
template <typename InputIterator, typename = std::iterator_traits<InputIterator>::value_type>
eigen& operator=(InputIterator first)
{
a = *first++;
b = *first++;
c = *first++;
return *this;
}
float a, b, c;
};
int main()
{
Eigen::Matrix3f A;
A << 1, 2, 3, 2, 4, 5, 3, 5, 6;
Eigen::EigenSolver<Eigen::Matrix3f> handle(A);
std::cout << "The matrix of eigenvectors, V, is: " << std::endl << handle.eigenvectors() << std::endl << std::endl;
std::cout << "The real part of first column is : " << std::endl <<
handle.eigenvectors().col(0).real() << std::endl << std::endl;
eigen e = handle.eigenvectors().col(0).real();
return 0;
}
How can I write code to generate a random number that falls between two different ranges?
Example: Generate a random number that is between 5 and 7 or between 10 and 12. Possible outcomes are 5, 6, 7, 10, 11, or 12.
UPDATE Second implementation added below
If you want to make this generic, you'll have to code it.
Two options come to mind:
discrete_distribution (just feed it 5,6,7,10,11,12)
generate numbers [0..6) and index into an array int arr[]={5,6,7,10,11,12}
The second:
Live On Coliru
#include <random>
#include <iostream>
int main()
{
using namespace std;
vector<int> arr = {5,6,7,10,11,12};
mt19937 prng { random_device {} () };
uniform_int_distribution<> dist(0, arr.size()-1);
int i = 10;
while (i--)
std::cout << arr[dist(prng)] << " ";
}
Prints
5 5 6 12 11 6 11 12 5 12
Or, similar of course
UPDATE
An alternative implementation that will scale for many segments or large segments, by using Boost Interval Container Library to efficiently represent the intervals that make up the domain:
Live On Coliru
template <typename T = int>
struct uniform_draw {
using set = boost::icl::interval_set<T>;
using ival = typename set::interval_type::type;
uniform_draw(std::initializer_list<ival> data)
: set_(make_set(data)), dist_(0, set_.size() - 1)
{ }
friend std::ostream& operator<<(std::ostream& os, uniform_draw const& ud) {
return os << ud.set_ << " (#samples:" << ud.set_.size() << ")";
}
template <typename Engine>
T operator()(Engine& engine) {
uintmax_t index = dist_(engine);
std::cout << " - index: " << index << " against " << set_ << "\n";
// I think this can be optimized. I just don't know how to elegantly do that / yet
for (auto& iv : set_) {
std::cout << " - index: " << index << " against " << iv << "\n";
if (index > size(iv)) {
index -= size(iv);
} else {
return iv.lower() + index;
}
}
throw std::range_error("uniform_draw");
}
private:
set make_set(std::initializer_list<ival> data) {
set r;
for (auto& el : data)
r.insert(el);
return r;
}
set const set_;
std::uniform_int_distribution<T> dist_; // TODO make_unsigned<T>?
};
Use it like your usual distribution:
mt19937 mt { random_device {} () };
uniform_draw<int> dist { {5, 7}, {10, 12} };
std::cout << dist << "\n";
for (int i = 0; i < 10; ++i)
std::cout << "RESULT: " << dist(mt) << "\n";
Prints e.g.:
{[5,7)[10,12)} (#samples:4)
7 7 6 11 6 6 7 7 7 6
Pick a random number 0 or 1. If this number is 0, pick a random number in the first range, otherwise pick a random number in the second range.
If you want each number in the two ranges to have equal probability, you could weight the first decision based on the sizes of the two ranges.
I see two ways to do this. Let's say your two ranges are [minA, maxA] and [minB, maxB] where maxA < minB (if not just swap the two ranges)
Solution 1:
1) Generate a random number X in [minA, maxB] first
2) if X falls (maxA,minB) goto 1)
3) At this point X is the output
Solution 2 (more efficient especially if the gap between the two ranges is big):
1) rangeA = maxA - minA, rangeB = maxB - minB;
2) generate a random number X within [0,rangeA+rangeB]
3) if X < rangeA then output minA+X else minB+X
I have a black box C++ function which I don't have access to its source code:
void blackbox(vector<int> &input);
This function modifies the element of the input vector in an unknown manner.
The problem I have now is that I want to apply the black box function only for a partial segment of a vector, for example,
the last 500 elements of a vector. So, this is the routine that I wrote to attain this goal:
vector<int> foo (5,1000);
vector<int> bar (foo.end()-500,foo.end());
blackbox(bar);
swap_ranges(foo.end()-500,foo.end(),bar.begin());
This code may work, but is there a better way to do this?
It would be good if I can define a vector reference only for a segment of
an existing vector, instead of creating a copy.
I am not so comfortable with the copying and swapping parts in the above code; since this routine is
invoked so frequently, I think the repeated copying and swapping slows down the code.
If I knew the exact operations done by the block box, I would rewrite the function so that it takes vector iterators as the input
arguments. Unfortunately, this is not possible at the moment.
There's no well-defined way to achieve this functionality. With huge caveats and warnings, it can (for one GCC version at least) be hacked as below, or you could perhaps write something with better defined behaviour but based on your compiler's current std::vector implementation....
So... hacked. This will not work if insert/erase/resize/reserve/clear/push_back or any other operation affecting the overall vector is performed. It may not be portable / continue working / work with all optimisation levels / work on Tuesdays / use at own risk etc.. It depends on the empty base class optimisation.
You need a custom allocator but there's a catch: the allocator can't have any state or it'll change the binary layout of the vector object, so we end up with this:
#include <iostream>
#include <vector>
template <typename Container> // easy to get this working...
void f(Container& v)
{
std::cout << "f() v.data() " << v.data() << ", v.size() " << v.size() << '\n';
for (int& n : v) n += 10;
}
void g(std::vector<int>& v) // hard to get this working...
{
std::cout << "g() v.data() " << v.data() << ", v.size() " << v.size() << '\n';
for (int& n : v) n += 100;
}
int* p_; // ouch: can't be a member without changing vector<> memory layout
struct My_alloc : std::allocator<int>
{
// all no-ops except allocate() which returns the constructor argument...
My_alloc(int* p) { p_ = p; }
template <class U, class... Args>
void construct(U* p, Args&&... args) { std::cout << "My_alloc::construct(U* " << p << ")\n"; }
template <class U> void destroy(U* p) { std::cout << "My_alloc::destroy(U* " << p << ")\n"; }
pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0)
{
std::cout << "My_alloc::allocate() return " << p_ << "\n";
return p_;
}
void deallocate(pointer p, size_type n) { std::cout << "deallocate\n"; }
template <typename U>
struct rebind { typedef My_alloc other; };
};
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << "main() v.data() " << v.data() << '\n';
My_alloc my_alloc(&v[3]); // first element to "take over"
std::vector<int, My_alloc> w(3, my_alloc); // num elements to "take over"
f(w);
g(reinterpret_cast<std::vector<int>&>(w));
for (int n : v) std::cout << n << ' ';
std::cout << '\n';
std::cout << "sizeof v " << sizeof v << ", sizeof w " << sizeof w << '\n';
}
Output:
main() v.data() 0x9d76008
My_alloc::allocate() return 0x9d76014
My_alloc::construct(U* 0x9d76014)
My_alloc::construct(U* 0x9d76018)
My_alloc::construct(U* 0x9d7601c)
f() v.data() 0x9d76014, v.size() 3
g() v.data() 0x9d76014, v.size() 3
0 1 2 113 114 115 6 7 8 9
sizeof v 12, sizeof w 12
My_alloc::destroy(U* 0x9d76014)
My_alloc::destroy(U* 0x9d76018)
My_alloc::destroy(U* 0x9d7601c)
deallocate
See it run here