I have the following code that appends a part of a vector to another.
#include <algorithm> // std::copy
#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>
using namespace std;
void copyVec(const std::vector<double> in, std::vector<double> &out, int start, unsigned int length) {
assert(start>=0 && in.size()>=start+length);
out.reserve(length);
cout << in.at(9) << endl;
out.insert(out.end(), &in.at(start), &in.at(start+length));
}
int main(int argc, char ** argv) {
int start = 0;
int end = 9;
int window_size = 10;
// initialize
vector<double> vec1 = vector<double>(window_size);
for (unsigned int i=0;i<window_size;++i) vec1[i] = i;
vector<double> vec2 = vector<double>(window_size);
for (unsigned int i=0;i<window_size;++i) vec2[i] = i*10;
// print
cout << "vec1: ";
for (unsigned int i=0;i<vec1.size();++i) cout << vec1[i] << " "; cout << endl;
cout << "vec2: ";
for (unsigned int i=0;i<vec2.size();++i) cout << vec2[i] << " "; cout << endl;
copyVec(vec1,vec2,start,end);
// print
cout << "vec2: "; for (unsigned int i=0;i<vec2.size();++i) cout << vec2[i] << " "; cout << endl;
return 0;
}
I cannot seem to be able to access vec2's last element by reference.
The output for this example (int end = 9) is
size: 10 start: 0 end: 9
vec1: 0 1 2 3 4 5 6 7 8 9
vec2: 0 10 20 30 40 50 60 70 80 90
in[9]: 9 &in[9]: 0x186d118
vec2: 0 10 20 30 40 50 60 70 80 90 0 1 2 3 4 5 6 7 8
and, of course, for int end = 10 I get an out of range error:
size: 10 start: 0 end: 10
vec1: 0 1 2 3 4 5 6 7 8 9
vec2: 0 10 20 30 40 50 60 70 80 90
in[9]: 9 &in[9]: 0xae1118
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
Aborted (core dumped)
So how should I (efficiently) append the last vector element?
Your insert should use iterator directly:
out.insert(out.end(), in.begin() + start, in.begin() + (start + length));
The correct function will look like
#include <iterator>
#include <vector>
//...
void copyVec( const std::vector<double> &in,
std::vector<double> &out,
std::vector<double>::size_type start,
std::vector<double>::size_type length )
{
assert( in.size() >= start + length );
out.reserve( out.size() + length );
out.insert( out.end(), std::next( in.begin(), start ),
std::next( in.begin(), start + length ) );
}
The first parameter is declared as constant reference. You should reserve memory for the destination vector taking into account its current size.
It is better to use own iterators of the vector instead of the raw pointers.
start and start + length specify a range like [start, start + length )
For example to copy the entire vector you can write
copyVec2b(vec1, vec2, 0, vec1.size() );
In general you may not write in the function like
cout << in.at( start + length ) << endl;
because index start + length is not included in the range of copied elements.
You may write
if ( length != 0 ) cout << in.at( start + length - 1 ) << endl;
Related
I have this code which outputs: 10 5 16 8 4 2 11
However, I don't have any clue from where the 11 is coming from since when tracing i get the following:
H(10)
H(5)
1+H(16) //does this result in 17?
H(8)
H(4)
H(2)
H(1) -> returns 0
Moreover what happens to the (1) in 1+H(16) ?
Thus shouldnt my output of the n values be: 10 5 17 8 4 2 1
#include <iostream>
using namespace std;
int H ( int n ) {
cout << " " << n<<" ";
if ( n == 1 ) return 0;
if ( n%2 != 0 ) return 1 + H ( 3*n + 1 );
else return H ( n/2 );
}
int main() {
// for ( int i=0; ++i<=20; )
// cout << H(i) << endl;
cout << H(10) << endl;
}
At the end of the recursion, the function prints 1 then the stack pops everything out and the main prints the returned value 1 (0 is returned at the end of the recursion and only the call to H(5) adds one to the result), so 11 is printed.
I would like to represent a std::vector of a structure containing several integers as a "flatten" vector of integers, without copying the data.
I tried something with a reinterpret_cast as shown below:
#include <vector>
#include <iostream>
struct Tuple
{
int a, b, c;
};
int main()
{
// init
std::vector<Tuple> vec1(5);
for(size_t i=0; i<vec1.size(); ++i)
{
vec1[i].a = 3 * i + 0;
vec1[i].b = 3 * i + 1;
vec1[i].c = 3 * i + 2;
}
// flattening
std::vector<int>* vec2 = reinterpret_cast<std::vector<int>*>(&vec1);
// print
std::cout << "vec1 (" << vec1.size() << ") : ";
for(size_t i=0; i<vec1.size(); ++i)
{
std::cout << vec1.at(i).a << " " << vec1.at(i).b << " " << vec1.at(i).c << " ";
}
std::cout << std::endl;
std::cout << "vec2 (" << vec2->size() << ") : ";
for (size_t j = 0; j < vec2->size(); ++j)
{
std::cout << vec2->at(j) << " ";
}
std::cout << std::endl;
return 0;
}
which works well since the output is:
vec1 (5) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
vec2 (15) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
My questions are :
Is this behavior compiler dependent? (I am using g++ 6.3.0)
How vec2 knows that the size of the vector is 15 and not 5?
Is their any other solution avoiding the use of reinterpret_cast? (If I "accidentally" add a double member to Tuple, the resulting issue could be hard to track...)
If vec1 has a specific allocator: std::vector<Tuple,A<Tuple>>, what should be the type of vec2? std::vector<int> or std::vector<int,A<int>> or std::vector<int,A<Tuple>>?
You can't legally reinterpret_cast the entire vector to a different type of vector. But you can legally cast a pointer to struct to a pointer to the first element of that struct. So this works:
std::vector<Tuple> vec1(5);
int* vec2 = &vec1.front().a;
size_t vec2_size = vec1.size() * sizeof(vec1[0]) / sizeof(vec2[0]);
for (size_t j = 0; j < vec2_size; ++j)
{
std::cout << vec2[j] << " ";
}
You need to make sure there's no padding in Tuple, so:
static_assert(sizeof(Tuple) == 3 * sizeof(int), "Tuple must be 3 ints");
To answer your bulleted questions:
Is this behavior compiler dependent?
Your code was illegal.
How vec2 knows that the size of the vector is 15 and not 5?
You got lucky, your code was illegal.
Is their any other solution avoiding the use of reinterpret_cast?
See above.
If vec1 has a specific allocator: std::vector>, what should be the type of vec2?
Same as above, int*.
I think Eigen uses compressed methods to store sparse matrices. Is there any way that I can extract Triplet-format vectors of an Eigen sparse matrix in from of std::vectors?
Thanks.
More info (an example of triplet format)
Triplet format of matrix :
A=
3 0 4 0
0 0 1 0
0 2 0 5
4 0 0 0
i = 1 1 2 3 3 4 // row
j = 1 3 3 2 4 1 // column
S = 3 4 1 2 5 4 // values
The answer to the question, which is:
// Is there some method such as:
std::vector<Eigen::Triplet<double>> T = SparseMat.to_triplets();
// in Eigen?
Is no, there does not appear to be such a function.
Instead,
std::vector<Eigen::Triplet<double>> to_triplets(Eigen::SparseMatrix<double> & M){
std::vector<Eigen::Triplet<double>> v;
for(int i = 0; i < M.outerSize(); i++)
for(typename Eigen::SparseMatrix<double>::InnerIterator it(M,i); it; ++it)
v.emplace_back(it.row(),it.col(),it.value());
return v;
}
auto t = to_triplets(SparseMat);
And if you want to do it faster, open it in an IDE, look around for pointers to the data arrays, and write a convoluted function that will have no effect on runtime, since the matrix is sparse, and copying is linear in terms of nonzero elements.
Simply as shown in the tutorial:
#include <Eigen/Sparse>
#include <iostream>
using namespace Eigen;
using std::cout;
using std::endl;
typedef Triplet<int> Trip;
int main(int argc, char *argv[]){
std::vector<Trip> trp, tmp;
// I subtracted 1 from the indices so that the output matches your question
trp.push_back(Trip(1-1,1-1,3));
trp.push_back(Trip(1-1,3-1,4));
trp.push_back(Trip(2-1,3-1,1));
trp.push_back(Trip(3-1,2-1,2));
trp.push_back(Trip(3-1,4-1,5));
trp.push_back(Trip(4-1,1-1,4));
int rows, cols;
rows = cols = 4;
SparseMatrix<int> A(rows,cols);
A.setFromTriplets(trp.begin(), trp.end());
cout << "Matrix from triplets:" << endl;
cout << A << endl;
cout << endl << "Triplets:" << endl;
cout << "Row\tCol\tVal" <<endl;
for (int k=0; k < A.outerSize(); ++k)
{
for (SparseMatrix<int>::InnerIterator it(A,k); it; ++it)
{
cout << 1+it.row() << "\t"; // row index
cout << 1+it.col() << "\t"; // col index (here it is equal to k)
cout << it.value() << endl;
}
}
return 0;
}
I have a multi set of int . C++
multiset<int>t;
I need to find the position of the first element which is greater than of equal to val. I used lower_bound for this
multiset<int>::iterator it= lower_bound(t[n].begin(), t[n].end(), val);
but can not find the the relative position from the beginning of the multi set .
As The Cplusplus.com suggests using.. for vector.
// lower_bound/upper_bound example
#include <iostream> // std::cout
#include <algorithm> // std::lower_bound, std::upper_bound, std::sort
#include <vector> // std::vector
int main () {
int myints[] = {10,20,30,30,20,10,10,20};
std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
std::vector<int>::iterator low,up;
low=std::lower_bound (v.begin(), v.end(), 20); // ^
up= std::upper_bound (v.begin(), v.end(), 20); // ^
std::cout << "lower_bound at position " << (low- v.begin()) << '\n';
std::cout << "upper_bound at position " << (up - v.begin()) << '\n';
return 0;
}
Can I do it in multi set .. ?
Another question is : Can I merge to multi set like vectors like shown bellow , v1,v2,v are vectors ?
merge(v1.begin(),v1.end(),v2.begin(),v1.end(),back_inserter(v))
The generic way to get the distance between two iterators is to call std::distance.
auto it = std::lower_bound(t[n].begin(), t[n].end(), val);
const auto pos = std::distance(t[n].begin(), it);
For std::multiset, member types iterator and const_iterator are bidirectional iterator types. Bidirectional iterator does not support arithmetic operators + and - (for details check cppreference).
std::distance can be used to calculate the number of elements between two iterators.
std::distance uses operator- to calculate the number of elements if parameter is a random-access iterator. Otherwise, it uses the increase operator (operator++) repeatedly.
Here is a slightly changed code snippet from cppreference.
#include <iostream>
#include <set>
int main ()
{
std::multiset<int> mymultiset;
std::multiset<int>::iterator itlow, itup;
for (int i = 1; i < 8; i++) mymultiset.insert(i * 10); // 10 20 30 40 50 60 70
itlow = mymultiset.lower_bound(30);
itup = mymultiset.upper_bound(40);
std::cout << std::distance(mymultiset.begin(), itlow) << std::endl;
std::cout << std::distance(mymultiset.begin(), itup) << std::endl;
mymultiset.erase(itlow, itup); // 10 20 50 60 70
std::cout << "mymultiset contains: ";
for (std::multiset<int>::iterator it = mymultiset.begin(); it != mymultiset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Output
2
4
mymultiset contains: 10 20 50 60 70
You can merge the std::multiset with std::multiset::insert member function as following;
#include <iostream>
#include <set>
int main ()
{
std::multiset<int> mset1;
std::multiset<int> mset2;
for (int i = 1; i < 8; i++) mset1.insert(i * 10); // 10 20 30 40 50 60 70
for (int i = 1; i < 8; i++) mset2.insert(i * 10); // 10 20 30 40 50 60 70
mset1.insert(mset2.begin(), mset2.end());
std::cout << "mset1 contains: ";
for (std::multiset<int>::iterator it = mset1.begin(); it != mset1.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Output
mset1 contains: 10 10 20 20 30 30 40 40 50 50 60 60 70 70
We have a class example and I just don't get it. I don't quite understand how the operator() works in this case, and everything starting with sort. I looked at the output after running the program, and I don't see how those values are obtained.
sort indices array: 2 8 10 4 1 7 5 3 0 9 6 11
replay numbers array: 37 33 29 36 32 35 39 34 30 38 31 40
number array via indices 29 30 31 32 33 34 35 36 37 38 39 40
I tried looking up functors on this board since the title is functor example, but I guess I don't see how functors are in play here. Any thoughts would be GREATLY appreciated as I am COMPLETELY lost. Thanks!
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include "IndexCompare.h"
using namespace std;
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
while (first != last) {
*first++ = value++;
}
}
const int MAX = 12;
int main() {
int numbers[] = {37, 33, 29, 36, 32, 35, 39, 34, 30, 38, 31, 40};
vector<int> vecNum(numbers, numbers + MAX);
// Display original number array.
cout << "--- initial numbers array ---" << endl;
vector<int>::iterator iter = vecNum.begin();
for (; iter != vecNum.end(); iter++ ) {
cout << *iter << " ";
}
cout << "\n";
vector<int> indices( vecNum.size() );
// fill indices array
cout << "\n--- invoke 'iota' on indices array ---";
iota( indices.begin(), indices.end(), 0 );
// Display original indices array.
cout << "\n linear indices array: ";
vector<int>::iterator iterIdx = indices.begin();
for (; iterIdx != indices.end(); iterIdx++ ) {
cout << *iterIdx << " ";
}
cout << "\n";
// sort indices array
cout << "\n--- invoke 'Sort' on indices based on number array ---";
sort(indices.begin(), indices.end(),
IndexCompare<vector<int>::iterator>(vecNum.begin(),vecNum.end()));
// Display sorted indices array
cout << "\n Sorted indices array: ";
for (iterIdx = indices.begin(); iterIdx != indices.end(); iterIdx++ ) {
cout << *iterIdx << " ";
}
cout << "\n";
cout << "\n--- Run check on number array indexed normally ---";
// Display original numbers array.
cout << "\n replay numbers array: ";
iter = vecNum.begin();
for (; iter != vecNum.end(); iter++ ) {
cout << *iter << " ";
}
cout << "\n";
cout << "\n--- Run check on number array indexed with sorted indices ---";
// Print original nums array indirectly through indices.
cout << "\n number array via indices: ";
for (int index = 0; index < vecNum.size(); index++ )
cout << vecNum[indices[index]] << " ";
cout << "\n";
getchar();
return 0;
}
// IndexCompare.h - interface for IndexCompare class template
#ifndef _INDEXCOMPARE_H_
#define _INDEXCOMPARE_H_
#pragma once
template <class random_iterator>
class IndexCompare {
public:
IndexCompare(random_iterator begin, random_iterator end)
: begin(begin), end(end) {}
~IndexCompare() {}
bool operator() (unsigned int first, unsigned int second) {
return (*(begin + first) < *(begin + second));
}
private:
random_iterator begin;
random_iterator end;
};
#endif
I am not sure I will be able to explain this correctly. Here is my try:
(1). vector<int> indices( vecNum.size() );
You are creating a vector to hold the indexes for the elements in vector vecNum. Obviously the number of elements in this vector is same as number of elements in vecNum.
(2). iota( indices.begin(), indices.end(), 0 );
Initializing the indices with values from 0 - vecNum.size() - 1
(3).
sort(indices.begin(), indices.end(),
IndexCompare<vector<int>::iterator>(vecNum.begin(),vecNum.end()));
For each element in the indices vector invoke the functor IndexCompare. This functor in its operator() gets the value from the vecNum vector corresponding to the given index position. So basically you are sorting the indices vector (not vecNum) based on the values in vecNum. Hence the vecNum remains unaffected and indices gets sorted based on the values from vecNum.
To make it more clearer (I hope), the initial state of the indices vector will be say:
indices = 0,1,2
and vecNum = 20,10,30
Now you are calling std::sort on this with your own functor. So to determine whether 0 is less than 1 sort algorithm will use your functor. Inside the functor you are determinng whether 0 < 1 using the logic whether vecNum[0] (i.e. 20) < vecNum[1] (i.e. 10). So the sorted out put will be indices = 1,0,2.