Find difference between two lists using Eigen - c++

I would like to find the difference between two lists. For example:
// two lists:
A = [ 0, 1, 2, 3, 4, 5, 6 ];
B = [ 1, 4, 5 ];
// difference between the lists:
C = [ 0, 2, 3, 6 ];
I have done this using the STL-library of C++ as follows:
#include <iostream>
#include <vector>
int main()
{
std::vector<size_t> A = {0, 1, 2, 3, 4, 5, 6};
std::vector<size_t> B = {1, 4, 5};
std::vector<size_t> C;
std::set_difference(A.begin(),A.end(), B.begin(),B.end(), std::inserter(C,C.begin()));
return 0;
}
However, because my application uses mostly Eigen, I now would like to do also this using Eigen. I couldn't find what I was looking for in the documentation nor online.
Note that I specifically want to avoid writing my own function.

Here you go:
#include <iostream>
#include <Eigen/Dense>
int main()
{
using namespace Eigen;
VectorXd a(3), b(1);
VectorXd c(a.size());
a << 1,2,3;
b << 1;
auto it = std::set_difference(a.data(), a.data() + a.size(),
b.data(), b.data() + b.size(),
c.data());
c.conservativeResize(std::distance(c.data(), it)); // resize the result
std::cout << c;
}
The key here is to use Eigen::VectorXd::data() member function, which returns a pointer to the underlying storage, which is itself an iterator that can be passed around to C++ standard library functions.

Related

Find unique element in sorted array using c++

I am trying to find unique element from the array these is question
Input : arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5}
Output : arr[] = {1, 2, 3, 4, 5}
They give me correct output but why they give 0 at the end in output:
these is my output:
{1,2,3,4,5,0}
Code:
#include<iostream>
using namespace std;
int main(){
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0;j<=n;j++){
if(arr[j]!=arr[j+1]){
cout<<arr[j];
}
}
}
Except for std::cout, you code is much more C than ++.
std::unique of the C++ Standard Library does exactly what you want. There is no need to re-implement this.
Next there is the erase-remove idiom to delete the superfluous elements.
For the output, you can use std::for_each() or at least a range-based for loop.
And also, you don't want using namespace std;
A more modern solution looks like this:
#include <iostream>
#include <algorithm>
#include <vector>
int main(){
std::vector<int> arr {1, 2, 2, 3, 4, 4, 4, 5, 5};
auto last = std::unique(arr.begin(), arr.end());
arr.erase(last, arr.end());
std::for_each(arr.begin(), arr.end(), [](int n){std::cout << n << std::endl;} );
}
Try it on Godbolt.
problem is in for loop becouse you use less or equal to n.
you need to use just less then n becouse array starts from zero that means you asking for sixth element that do not have alocalizated in memory
now it should be correct
#include<iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0; j<n; j++) {
if (arr[j]!=arr[j+1]) {
cout<<arr[j];
}
}
}

c++ check if array equals array not made

Ddoes any body know how do do this? Thanks if you do. I am new in c++. I don't know what do do. Python is much better in my opinion.
#include <bits/stdc++.h>
using namespace std;
int main(){
int nums[] = {1, 2, 3, 4};
if (nums == [1, 2, 3, 4]){
cout<<1;
}
}
You should use std::array instead of plain arrays to realize this.
#include <iostream>
#include <array>
int main(void) {
std::array<int, 4> nums = {1, 2, 3, 4};
if (nums == std::array<int, 4>{1, 2, 3, 4}){
std::cout<<1;
}
}
Also see:
c++ - Why is "using namespace std;" considered bad practice? - Stack Overflow
c++ - Why should I not #include <bits/stdc++.h>? - Stack Overflow
From C++17, you can use class template argument deduction to simplify MikeCAT's solution like this:
std::array nums = {1, 2, 3, 4};
if (nums == std::array{1, 2, 3, 4}) {
std::cout << 1;
}

How to make space between array values in printing?

I'm interested, how could i get same result in C++. For this C code:
for(i=0;i<n;i++)
printf("%4d",array[i]);
This will create 4 space gap between my values from array.
Is there something similar in C++?
The same code works in C++:
const int n = 10;
int array[n] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i=0;i<n;i++)
printf("%4d",array[i]);
But if you're looking for more a C++-esque way of doing things, you can use std::cout and std::setw:
#include <iostream> // cout
#include <iomanip> // setw
int main()
{
int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto n : array)
{
std::cout << std::setw(4) << n;
}
}

C++ "select" algorithm

Among the functionalities found in std::algorithm I can't seem to find one of the most basic I can think of: selected a subset of a collection (for example, return all the odd numbers, all the employees that have status == 'employed', all items that cost less that 20 dollars).
So, given a list of ints like
vector<int> ints {1, 9, 3, 27, 5, 19, 3, 8, 2, 12};
vector<int> evens = ?
vector<int> greaterThan7 = ?
How to find those that are even and those that are greater than 7?
If you want something more functional, you can check out the boost range library. Specifically, filtered:
for (int i : ints | filtered([](int i){return i > 7;}))
{
...
}
This gives you a lazy view, without constructing a new container.
You can get the same from Eric Niebler's range-v3:
for (int i : view::filter(ints, [](int i){return i > 7;})
{
...
}
with the benefit that you can just assign that to a vector too (so you can choose if it's lazy or eager, which Boost.Ranges does not allow).
std::vector<int> greaterThan7 = view::filter(ints, [](int i){return i > 7;});
std::vector<int> sameThing = ints | view::filter([](int i){return i > 7;});
For example
vector<int> ints {1, 9, 3, 27, 5, 19, 3, 8, 2, 12};
vector<int> evens;
std::copy_if( ints.begin(), ints.end(), std::back_inserter( evens ),
[]( int x ) { return x % 2 == 0; } );
Here is a demonstrative program
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> ints { 1, 9, 3, 27, 5, 19, 3, 8, 2, 12 };
std::vector<int> evens;
std::copy_if( ints.begin(), ints.end(), std::back_inserter( evens ),
[]( int x ) { return x % 2 == 0; } );
for ( int x : evens ) std::cout << x << ' ';
std::cout << std::endl;
}
Its output is
8 2 12
Depending on what your exact requirements are, consider std::stable_partition (or std::partition). It reorders elements in the range such that all which satisfy a predicate come first. You can think of it as splitting the range into a "subset" and a "not subset" part. Here is an example:
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
using std::begin;
using std::end;
using std::cbegin;
using std::cend;
std::vector<int> ints { 1, 9, 3, 27, 5, 19, 3, 8, 2, 12 };
auto const greater_than_7 = [](int number) { return number > 7; };
auto const iter_first_not_greater_than_7 = std::stable_partition(begin(ints), end(ints), greater_than_7);
for (auto const_iter = cbegin(ints); const_iter != iter_first_not_greater_than_7; ++const_iter)
{
std::cout << *const_iter << "\n";
}
}
If, however, you are fine with copying each matching element to a new collection, for example because the source range must not be modified, then use std::copy_if.
Perhaps what you are really looking for is a view of an unmodifiable range. In this case, you are approaching the problem from the wrong direction. You don't need a particular algorithm; a more natural solution to the problem would be a filtering iterator, like for example Boost's Filter Iterator. You can use the one in Boost or study its implementation to learn how you could write filtering iterators yourself.

Efficiently sort subset of the vector that defines the order

I have the vector that defines the order of items (0..N-1), e.g.
{5, 0, 4, 3, 2, 1, 7, 6}.
I have to sort subsets of that vector. So, for {0, 1, 2, 5} I should get {5, 0, 2, 1}.
I tested the following solutions:
Create a set of items in a subset, then clear the subset, go through the ordering vector, adding only items in the set.
Create new sorted vector by going through the ordering vector, adding only items found by in the subset by std::lower_bound.
The second solution seems much faster, although it needs subset to be sorted. Are there any better solutions? I am using C++/STL/Qt, but the problem is probably not language-dependent.
Check this code :-
#include <iostream>
#include <algorithm>
#include <vector>
struct cmp_subset
{
std::vector<int> vorder;
cmp_subset(const std::vector<int>& order)
{
vorder.resize(order.size());
for (int i=0; i<order.size(); ++i)
vorder.at(order[i]) = i;
}
bool operator()(int lhs, int rhs) const
{
return vorder[lhs] < vorder[rhs];
}
};
int main()
{
std::vector<int> order = {5, 0, 4, 3, 2, 1, 7, 6};
std::vector<int> subset = {0, 1, 2, 5};
for (auto x : subset)
std::cout << x << ' ';
std::cout << '\n';
std::sort(subset.begin(), subset.end(), cmp_subset(order));
for (auto x : subset)
std::cout << x << ' ';
std::cout << '\n';
return 0;
}
The code is copied from here