This question already has answers here:
Skip an entry of a random iterator
(2 answers)
Closed 8 years ago.
(Caveat: I'm a beginner in C++).
Consider this simple example:
#include <iostream>
#include <random>
#include <algorithm>
using namespace std;
template<class RandomAccessIterator1>
typename std::iterator_traits<RandomAccessIterator1>::value_type
foo(RandomAccessIterator1 firsta,RandomAccessIterator1 lasta,float store[]){
const float x1=*firsta;
int i=0;
for (RandomAccessIterator1 it=firsta;it!=lasta+1;it++){
store[i++]=x1-*it;
}
return(*(firsta+3));
}
int main(){
const int n=*nr;
int i;
float x[n],store[n];
for(i=0;i<n;i++) x[i]=(float)rand()/(float)RAND_MAX;
std::sort(x,x+n);
float a2=(x[1]+x[n-1])*0.5f;
int m0=std::upper_bound(x,x+n,a2)-x;
int m1=m0/2-1;
float var=foo(x,x+m0,store);
for(i=0;i<m0-1;i++) std::cout<< store[i] << std::endl;
}
My problem is that I need foo to not take x[m1] into account. Simply 'forget' that element as it were. But I don't really have access to the real foo itself: everything has to be done on the level of the inputs to foo, not the function itself. In other word, I need to somehow make firsta,lasta the bounds of
an RandomAccessIterator that contains all the elements in the range [firsta,lasta) except the m1-th. I don't have anything against using boost or other external
open source libraries. My only problem is that whatever solution should be O(1).
Oh, and I don't even know if it is possible.
I put the tag boost because there seems to be a series of related question on SO that solve this problem using boost.
If you can't do anything in foo that only really leaves you with the option of copying everything but the m1-th value into a vector (or some other random access container).
You could create a new iterator class that knows about values to skip. Something that looks roughly like this:
class MyIterator
{
public:
MyIterator(containerClass & myContainer, value_type valueToSkip);
private:
containerClass::iterator baseIterator;
value_type skipValue;
};
Obviously I've left out a lot of the details.
Related
This question already has answers here:
Iterate throught n-dimensional vector c++
(2 answers)
how to print an n-dimensional array in c++
(2 answers)
Closed 28 days ago.
I am learning template programming. While doing so, I am trying to implement a template function to read n-dimensional vector.
My thought process is to recursively read through all dimensions and once I reach the innermost vector, start reading its elements.
Below is the (incorrect)code that I have tried.
template<typename Container>
void read_vectors(Container c){
read_vectors<decltype(begin(c))>(begin(c));
}
template<>
void read_vectors(vector<int> container){
for(auto i:container)
cout<<i<<endl;
}
int main(){
vector<vector<vector<int>>> intvectors{{{1,2,3},{1,2,3}},{{1,2,3}, {1,2,3}}};
read_vectors(intvectors);
return 0;
}
Any pointers on how that can be achieved is helpful.
Firstly, passing function parameters by value creates a copy of the function parameter:
template<>
void read_vectors(vector<int> container){
When this is reached, a complete copy of the passed-in vector is made just for the purpose of passing in this parameter. This accomplishes absolutely nothing at all, whatsoever, except to waste memory and precious electrons. In this case, the parameters should be passed by reference.
Secondly, for all other dimensions it's also necessary to iterate over all the other dimensions too. Nothing is going to iterate over them, automatically. So the final solution is:
#include <vector>
#include <iostream>
using namespace std;
template<typename Container>
void read_vectors(const Container &c)
{
for (const auto &i:c)
{
read_vectors(i);
}
}
template<>
void read_vectors(const vector<int> &container){
for(auto i:container)
cout<<i<<endl;
}
int main(){
vector<vector<vector<int>>> intvectors{{{1,2,3},{1,2,3}},{{1,2,3}, {1,2,3}}};
read_vectors(intvectors);
return 0;
}
This question already has answers here:
How do I erase an element from std::vector<> by index?
(16 answers)
Closed 4 years ago.
I have an object that contains an STL vector. I start with the vector being size zero and use push_back to add to it. So, push_back works fine.
In my code, each element in the vector represents an atom. Thus the object this STL vector is inside is a "molecule".
When I try to remove an atom from my molecule i.e., erase one of the elements from the array, the erase() function does not work. Other methods do work such as size() and clear(). clear() removes all elements though, which is overkill. erase() is exactly what I want, but it doesn't work for some reason.
Here is an incredibly simplified version of my code. It does, however, represent the problem exactly.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class atomInfo
{
/* real code has more variables and methods */
public:
atomInfo () {} ;
};
class molInfo
{
/* There is more than 1 atom per molecule */
/* real code has more variables and methods */
public:
vector <atomInfo> atom;
molInfo () {};
};
int main ()
{
int i;
molInfo mol;
for( i=0; i<3 ; i++)
mol.atom.push_back( atomInfo() );
//mol.atom.clear() ; //Works fine
mol.atom.erase(1) ; //does not work
}
I get the following error when I use erase():
main.cpp: In function ‘int main()’: main.cpp:39:21: error: no matching
function for call to ‘std::vector::erase(int)’
mol.atom.erase(1) ;
It looks like you thought std::vector::erase took an index from the start of the container.
It's not clear where you got this idea from, as it is not what the documentation says.
These functions work with iterators.
Fortunately, with vectors, you can get the effect you want by adding a number to an iterator.
Like this:
mol.atom.erase(mol.atom.begin() + 1);
Said documentation in fact does have an example to this effect.
As programming becomes more complex, and the need to perform operations on struct data becomes visible. Is there a conversion method for converting a struct type into an array of its members such that:
struct FooDesc Foo{
int num_Foo;
int num_Bar;
int GreenFoo;
};
can be represented by:
int Bar[2];
Or better, dynamically as:
vector<int> Bar;
The goal is to convert or re-represent the data struct as an iteratable form, without the excessive use of the assignment operator.
You could use unnamed structs to make a hybrid struct where its member could be treated as an array:
struct Foo {
union {
struct {
int x;
int y;
int z;
};
struct {
int array[3];
};
};
};
LIVE DEMO
Note however, that unnamed struct comes from C11 and its not a standard C++ feature. It is supported as an extension though by GCC as well Clang.
If your structs are POD then you might consider using std::tuple instead of structs. You could then use various template facilities to work through the members of the tuple.
Here is a simple example that prints the elements of a tuple - using boost::fusion::tuple instead of the std::tuple since it has many more tuple-manipulating facilities available:
#include <boost/fusion/tuple.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <iostream>
struct Printer {
template<typename T>
void operator()(const T &t) const {
std::cout << t << std::endl;
}
};
int main(int argc, const char * argv[])
{
boost::fusion::tuple<int, int, int, int, float> t =
boost::fusion::make_tuple(3, 5, 1, 9, 7.6f);
boost::fusion::for_each(t, Printer());
return 0;
}
You could include these in unions with the struct but you'd want to do some testing to ensure proper alignment agreement.
The upside is that these manipulations are very fast - most of the work is done at compile time. The down-side is that you can't use normal control structs like indexing with runtime indices - you'd have to build an abstraction layer around that as the normal get<i>(tuple) accessor requires that i be a compile time constant. Whether this is worth the complexity depends strongly on the application.
How about:
vector <Foo> Bar;
You can then add instances of your struct and then access each element as desired, using an array-like format.
See this related question for further information:
Vector of structs initialization
Upon re-reading your question a few times, I think I mis-understood your intent and answered the "wrong question". You can make an array of your struct as mentioned above and index it as an array, but I don't believe it is quite as simple as that to make each struct element a different element of an array. If you are looking to make an array of structs, my answer should help. If you are looking to make each element of your struct an element of your array, 40two's answer should help you out.
This question already has answers here:
Standard library sort and user defined types
(3 answers)
Closed 8 years ago.
I'm trying to sort vector of struct, but it ends with error. I tried to do it according to C++ reference, but I don't know where the problem is. Could someone help me?
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/*
*
*/
struct reg{
string name;
string addr;
};
int main(int argc, char** argv) {
vector <reg> a;
reg newReg = { "John", "Street1"};
a.push_back(newReg);
reg newReg2 = { "Mike", "Street2"};
a.push_back(newReg2);
std::sort (a.begin(), a.end());
return 0;
}
Unlike build-in types like int, float etc, you have to define the compare function for struct reg, i.e. rules that you want the elements to follow when sorting. Like this:
bool my_compare(const struct reg &x, const struct reg &y)
{
// define how to compare x,y here
}
And then, you can pass this function to sort the vector:
std::sort (a.begin(), a.end(), my_compare);
You either have to overload the comparison operator (less than, afair) or provide a custom comparison function.
You need to tell std::sort what makes one instance of the struct "less than" another instance of the struct.
In other words, if I give you two instances of those structs filled with data, and ask you "which one is placed before the other?", what is your answer? The rules you used to come with that answer is what you need to code and give to the 3 argument version of std::sort.
I want to create an adjacency matrix for a graph. Since I read it is not safe to use arrays of the form matrix[x][y] because they don't check for range, I decided to use the vector template class of the stl. All I need to store in the matrix are boolean values. So my question is, if using std::vector<std::vector<bool>* >* produces too much overhead or if there is a more simple way for a matrix and how I can properly initialize it.
EDIT: Thanks a lot for the quick answers. I just realized, that of course I don't need any pointers. The size of the matrix will be initialized right in the beginning and won't change until the end of the program. It is for a school project, so it would be good if I write "nice" code, although technically performance isn't too important. Using the STL is fine. Using something like boost, is probably not appreciated.
Note that also you can use boost.ublas for matrix creation and manipulation and also boost.graph to represent and manipulate graphs in a number of ways, as well as using algorithms on them, etc.
Edit: Anyway, doing a range-check version of a vector for your purposes is not a hard thing:
template <typename T>
class BoundsMatrix
{
std::vector<T> inner_;
unsigned int dimx_, dimy_;
public:
BoundsMatrix (unsigned int dimx, unsigned int dimy)
: dimx_ (dimx), dimy_ (dimy)
{
inner_.resize (dimx_*dimy_);
}
T& operator()(unsigned int x, unsigned int y)
{
if (x >= dimx_ || y>= dimy_)
throw std::out_of_range("matrix indices out of range"); // ouch
return inner_[dimx_*y + x];
}
};
Note that you would also need to add the const version of the operators, and/or iterators, and the strange use of exceptions, but you get the idea.
Best way:
Make your own matrix class, that way you control every last aspect of it, including range checking.
eg. If you like the "[x][y]" notation, do this:
class my_matrix {
std::vector<std::vector<bool> >m;
public:
my_matrix(unsigned int x, unsigned int y) {
m.resize(x, std::vector<bool>(y,false));
}
class matrix_row {
std::vector<bool>& row;
public:
matrix_row(std::vector<bool>& r) : row(r) {
}
bool& operator[](unsigned int y) {
return row.at(y);
}
};
matrix_row& operator[](unsigned int x) {
return matrix_row(m.at(x));
}
};
// Example usage
my_matrix mm(100,100);
mm[10][10] = true;
nb. If you program like this then C++ is just as safe as all those other "safe" languages.
The standard vector does NOT do range checking by default.
i.e. The operator[] does not do a range check.
The method at() is similar to [] but does do a range check.
It will throw an exception on out of range.
std::vector::at()
std::vector::operator[]()
Other notes:
Why a vector<Pointers> ?
You can quite easily have a vector<Object>. Now there is no need to worry about memory management (i.e. leaks).
std::vector<std::vector<bool> > m;
Note: vector<bool> is overloaded and not very efficient (i.e. this structure was optimized for size not speed) (It is something that is now recognized as probably a mistake by the standards committee).
If you know the size of the matrix at compile time you could use std::bitset?
std::vector<std::bitset<5> > m;
or if it is runtime defined use boost::dynamic_bitset
std::vector<boost::dynamic_bitset> m;
All of the above will allow you to do:
m[6][3] = true;
If you want 'C' array performance, but with added safety and STL-like semantics (iterators, begin() & end() etc), use boost::array.
Basically it's a templated wrapper for 'C'-arrays with some NDEBUG-disable-able range checking asserts (and also some std::range_error exception-throwing accessors).
I use stuff like
boost::array<boost::array<float,4>,4> m;
instead of
float m[4][4];
all the time and it works great (with appropriate typedefs to keep the verbosity down, anyway).
UPDATE: Following some discussion in the comments here of the relative performance of boost::array vs boost::multi_array, I'd point out that this code, compiled with g++ -O3 -DNDEBUG on Debian/Lenny amd64 on a Q9450 with 1333MHz DDR3 RAM takes 3.3s for boost::multi_array vs 0.6s for boost::array.
#include <iostream>
#include <time.h>
#include "boost/array.hpp"
#include "boost/multi_array.hpp"
using namespace boost;
enum {N=1024};
typedef multi_array<char,3> M;
typedef array<array<array<char,N>,N>,N> C;
// Forward declare to avoid being optimised away
static void clear(M& m);
static void clear(C& c);
int main(int,char**)
{
const clock_t t0=clock();
{
M m(extents[N][N][N]);
clear(m);
}
const clock_t t1=clock();
{
std::auto_ptr<C> c(new C);
clear(*c);
}
const clock_t t2=clock();
std::cout
<< "multi_array: " << (t1-t0)/static_cast<float>(CLOCKS_PER_SEC) << "s\n"
<< "array : " << (t2-t1)/static_cast<float>(CLOCKS_PER_SEC) << "s\n";
return 0;
}
void clear(M& m)
{
for (M::index i=0;i<N;i++)
for (M::index j=0;j<N;j++)
for (M::index k=0;k<N;k++)
m[i][j][k]=1;
}
void clear(C& c)
{
for (int i=0;i<N;i++)
for (int j=0;j<N;j++)
for (int k=0;k<N;k++)
c[i][j][k]=1;
}
What I would do is create my own class for dealing with matrices (probably as an array[x*y] because I'm more used to C (and I'd have my own bounds checking), but you could use vectors or any other sub-structure in that class).
Get your stuff functional first then worry about how fast it runs. If you design the class properly, you can pull out your array[x*y] implementation and replace it with vectors or bitmasks or whatever you want without changing the rest of the code.
I'm not totally sure, but I thing that's what classes were meant for, the ability to abstract the implementation well out of sight and provide only the interface :-)
In addition to all the answers that have been posted so far, you might do well to check out the C++ FAQ Lite. Questions 13.10 - 13.12 and 16.16 - 16.19 cover several topics related to rolling your own matrix class. You'll see a couple of different ways to store the data and suggestions on how to best write the subscript operators.
Also, if your graph is sufficiently sparse, you may not need a matrix at all. You could use std::multimap to map each vertex to those it connects.
my favourite way to store a graph is vector<set<int>>; n elements in vector (nodes 0..n-1), >=0 elements in each set (edges). Just do not forget adding a reverse copy of every bi-directional edge.
Consider also how big is your graph/matrix, does performance matter a lot? Is the graph static, or can it grow over time, e.g. by adding new edges?
Probably, not relevant as this is an old question, but you can use the Armadillo library, which provides many linear algebra oriented data types and functions.
Below is an example for your specific problem:
// In C++11
Mat<bool> matrix = {
{ true, true},
{ false, false},
};
// In C++98
Mat<bool> matrix;
matrix << true << true << endr
<< false << false << endr;
Mind you std::vector doesn't do range checking either.