I'm new to functors theme, so I hope this question will be constructive.
I have array of strings (). I need to calculate the sum of lenghts of these strings with help of functors.
My code:
class LengthFinder{
private:
size_t sum;
public:
LengthFinder():sum(0){}
void operator()(string elem)
{
sum += elem.size();
}
operator int()
{
return sum;
}
};
int main(int argc, char* argv[])
{
vector< string > array;
array.push_back("string");
array.push_back("string1");
array.push_back("string11");
string elem;
int sum = std::for_each(array.begin(), array.end(), LengthFinder(/*??*/));
return 0;
}
What should I pass to LengthFinder(), to get each string and take it size?
Don't use for_each for this. It can be forced to do the job, but it's a fair amount of extra work because it's not really the right tool for the job.
What you want to use is std::accumulate, which is built for exactly the sort of thing you're doing.
struct length : std::binary_function<size_t, size_t, std::string> {
size_t operator()(size_t a, std::string const &b) {
return a+b.length();
}
};
// ...
int sum = std::accumulate(array.begin(), array.end(), 0, length());
As stated by the original poster of the question:
SOLUTION:
Nothing should go to the parameters of LengthFinder:
int sum = std::for_each(array.begin(), array.end(), LengthFinder());
Related
im pretty new in c++ and my problem is the following:
i need an array in which i want so save values. all valus are of the same type.
there are two cases: the array should save int values or float.
when i compile, i dont knwo yet which type it will be, so it has to be defined while executing the programm.
i tried something like this:
void* myArray;
int a = 10;
if(something){
myArray = new int[a];
}
else{
myArray = new float[a];
}
after this i want so calculate things with these values, but i always get errors because the array is still void
There are several ways of doing this in C++:
You could use a void* and add reinterpret_cast<...> as needed,
You could make an array of unions that have both an int and a float, or
You could use templates.
The first two approaches are idiomatic to C, but not to C++. Both approaches are workable, but they result in solutions that are hard to understand and maintain.
The third approach lets you do things very cleanly:
template <typename T>
void calc() {
// You could use std::vector<T> here for even better flexibility
T* a = new T[10];
... // Perform your computations here
delete[] a;
// You don't need a delete if you use std::vector<T>
}
int main() {
...
// You can make a type decision at runtime
if (mustUseInt) {
calc<int>();
} else {
calc<float>();
}
return 0;
}
struct calculator : public boost::static_visitor<> {
void operator()(const std::vector<int>& vi) const {
// evaluate the array as ints
}
void operator()(const std::vector<float>& vf) const {
// evaluate the array as floats
}
};
using nasty_array = boost::variant<std::vector<int>, std::vector<float>>;
std::unique_ptr<nasty_array> myArray;
int a = 10;
if (something) {
myArray.reset(std::vector<int>(a));
}
else {
myArray.reset(std::vector<float>(a));
}
boost::apply_visitor( calculator(), *myArray );
In C++, how to pass two dimensional array as parameter in a function and this function returns a two dimensional array?
if I have a array defined like this:
struct Hello
{
int a;
int b;
};
Hello hello[3][3] = {.......};
how to return the array above in a function?
Hello(&f(Hello(&In)[3][3])) [3][3] {
//operations
return In;
}
The answer depends on what you mean by a two-dimensional array.
The C++ way would be to have a std::vector<std::vector<Type> >, in which case the answer is like this
typedef std::vector<std::vector<myType> > Array2D;
Array2D f(const Array2D& myArray)
{
}
If you've allocated your array dynamically in Type** as in
Type** p = new Type*(n);
for(int i = 0; i < n; ++i)
{
p[i] = new Type(m);
}
then you can simply pass the Type** along with the dimensions.
... f(Type** matrix, int n, int m);
If you have a normal 2D array as
Type matrix[N][M];
then you can pass it as
template<int N, int M>
... f(Type (&matrix)[N][M]);
I have deliberately left the return type in the two previous examples blank because it depends on what are you returning (the passed array or a newly created one) and the ownership policy.
Hardly readable (typedef is recommended), but you can do it:
Hello(&f(Hello(&A)[3][3])) [3][3] {
// do something with A
return A;
}
You actually do not need to return if this is the same array. Return void instead - syntax will be much simpler.
I'd do it like this...
typedef std::vector< int > vectorOfInts;
typedef std::vector< vectorOfInts > vectorOfVectors;
vectorOfVectors g( const vectorOfVectors & voi ) {
std::for_each( voi.begin(), voi.end(), [](const vectorOfInts &vi) {
std::cout<<"Size: " << vi.size() << std::endl;
std::for_each( vi.begin(), vi.end(), [](const int &i) {
std::cout<<i<<std::endl;
} );
} );
vectorOfVectors arr;
return arr;
}
int main()
{
vectorOfVectors arr( 10 );
arr[0].push_back( 1 );
arr[1].push_back( 2 );
arr[1].push_back( 2 );
arr[3].push_back( 3 );
arr[3].push_back( 3 );
arr[3].push_back( 3 );
g( arr );
return 0;
}
here is the C++ sample
int a[1000] = {3,1,5,4}
int b[1000] = {7,9,11,3}
how do i make it so if i sort array a, array b also following array a
example
a[1000] = {1,3,4,5}
b[1000] = {9,7,3,11}
is it possible using sort function
sort(a,a+4)
but also sort array b aswell ?
edit: what if there are 3 arrays ?
Instead of using two arrays, can you use an array of pairs and then sort THAT using a special comparison functor rather than the default less-than operator?
The simplest way is to rearrange your data into an array-of-structs instead of a pair of arrays so that each datum is contiguous; then, you can use an appropriate comparator. For example:
struct CompareFirst
{
bool operator() (const std::pair<int,int>& lhs, const std::pair<int,int>& rhs)
{
return lhs.first < rhs.first;
}
};
// c[i].first contains a[i], c[i].second contains b[i] for all i
std::pair<int, int> c[1000];
std::sort(c, c+1000, CompareFirst());
If you can't refactor your data like that, then you need to define a custom class that acts as a RandomAccessIterator:
struct ParallalArraySortHelper
{
ParallelArraySortHelper(int *first, int *second)
: a(first), b(second)
{
}
int& operator[] (int index) { return a[index]; }
int operator[] const (int index) { return a[index]; }
ParallelArraySortHelper operator += (int distance)
{
a += distance;
b += distance;
return *this;
}
// etc.
// Rest of the RandomAccessIterator requirements left as an exercise
int *a;
int *b;
};
...
int a[1000] = {...};
int b[1000] = {...};
std::sort(ParallalArraySortHelper(a, b), ParallelArraySortHelper(a+1000, b+1000));
Generate an array the same size as the original, containing the indexes into the array: {0, 1, 2, 3}. Now use a custom comparator functor that compares the elements in an associated array rather than the indexes themselves.
template<typename T>
class CompareIndices
{
public:
CompareIndices(const T * array) : m_AssociatedArray(array) {}
bool operator() (int left, int right) const
{
return std::less(m_AssociatedArray[left], m_AssociatedArray[right]);
}
private:
const T * m_AssociatedArray;
};
std::sort(i, i+4, CompareIndices(a));
Once you have a sorted list of indices, you can apply it to the original array a, or any other b array you want.
I'm facing a problem in C++ for which I currently don't have an elegant solution. I'm receiving data in the following format:
typedef struct {
int x;
int y;
int z;
}Data3D;
vector<Data3D> v; // the way data is received (can be modified)
But the functions that do the computations receive parameters like this:
Compute(int *x, int *y, int *z, unsigned nPoints)
{...}
Is there a way to modify the way data is received Data3D so that the memory representation would change from:
XYZXYZXYZ
to
XXXYYYZZZ
What I'm looking for is some way of populating a data structure in a similar way we populate an array but that has the representation above (XXXYYYZZZ). Any custom data structures are welcome.
So I want to write something like (in the above example):
v[0].x = 1
v[0].y = 2
v[0].y = 0
v[1].x = 6
v[1].y = 7
v[1].z = 5
and to have the memory representation below
1,6...2,7....0,5
1,6 is the beginning of the x array
2,7 is the beginning of the y array
0,5 is the beginning of the z array
I know that this can be solved by using a temporary array but I'm interested to know if there are other methods for doing this.
Thanks,
Iulian
LATER EDIT:
Since there are some solutions that change only the declaration of Compute function without changing its code - this should be taken into account also. See the answers related to the solution that involves using an iterator.
Iterator-based solution
An elegant solution would be to make Compute() accept iterators instead of pointers. The iterators you provide will have an adequate ++ operator (see boost::iterator for an easy way to build them)
Compute(MyIterator x, MyIterator y, MyIterator z);
There are normally very few changes to make to the function body, since *x, x[i] or ++x will be handled by MyIterator to point to the right memory location.
Quick'n Dirty solution
A less elegant but more straightforward solution is to hold your Data in the following struct
typedef struct {
std::vector<int> x;
std::vector<int> y;
std::vector<int> z;
}DataArray3D;
When receiving the data fill your struct like
void Receive(const Data3D& data, DataArray3D& array)
{
array.x.push_back(data.x);
array.y.push_back(data.y);
array.z.push_back(data.z);
}
and call Compute like this (Compute itself is unchanged)
Compute(&array.x[0], &array.y[0], &array.z[0]);
You could of course change your computer function.
I assume that all operation done on your int* in compute are dereference and increment operation.
I did not test it but you could pass in a structure like this
struct IntIterator
{
int* m_currentPos;
IntIterator(int* startPos):m_currentPos(startPos){};
IntIterator& operator++()
{
m_currentPos += 3;
return *this;
}
IntIterator& operator++(int)
{
m_currentPos += 3;
return *this;
}
int operator*()
{
return *m_currentPos;
}
int& operator[](const int index)
{
return m_currentPos[index*3];
}
};
And initialize it with this
std::vector<Data3D> v;
IntIterator it(&v[0].x);
Now all you need to do is change the type of your compute function arguments and it should do it. If of course some pointer arithmetics are used than it is getting more complex.
Reasonably elegant would be (not compiled/tested):
struct TempReprPoints
{
TempReprPoints(size_t size)
{
x.reserve(size); y.reserve(size); z.reserve(size);
}
TempReprPoints(const vector<Data3D> &v)
{
x.reserve(v.size()); y.reserve(v.size()); z.reserve(v.size());
for (size_t i = 0; i < v.size(); ++i ) push_back(v[i]);
}
void push_back(const Data3D& data)
{
x.push_back(data.x); y.push_back(data.y); z.push_back(data.z);
}
int* getX() { return &x[0]; }
int* getY() { return &y[0]; }
int* getZ() { return &z[0]; }
size_t size() { return x.size(); }
std::vector<int> x;
std::vector<int> y;
std::vector<int> z;
};
So you can fill it with a loop or even try to make the std::back_inserter work with it.
In order to get the syntax you want, you could use something like this.
struct Foo {
vector<int> x;
vector<int> y;
vector<int> z;
struct FooAccessor {
FooAccessor(Foo & f, int i) : x(f.x[i]), y(f.y[i]), z(f.z[i]) {}
int &x, &y, &z;
};
FooAccessor operator[](int i) {
return FooAccessor(*this, i);
}
};
int main() {
Foo f;
f.x.resize(10);
f.y.resize(10);
f.z.resize(10);
f[0].x = 1;
f[1].y = 2;
f[2].z = 3;
for (size_t p = 0; p < 10; ++p) {
cout << f.x[p] << "," << f.y[p] << "," << f.z[p] << endl;
}
}
I'd consider this an ugly solution - changing the way you access your data would likely be "better".
I need to get an input N from the user and generate a N*N matrix. How can I declare the matrix? Generally, the size of the array and matrix should be fixed at the declaration, right?
What about vector<vector<int>> ? I never use this before so I need suggestion from veteran.
A vector<vector<int>> (or vector<vector<int> >, for older compilers) can work well, but it's not necessarily the most efficient way to do things1. Another that can work quite nicely is a wrapper around a single vector, that keeps track of the "shape" of the matrix being represented, and provides a function or overloaded operator to access the data:
template <class T>
class matrix {
int columns_;
std::vector<T> data;
public:
matrix(int columns, int rows) : columns_(columns), data(columns*rows) {}
T &operator()(int column, int row) { return data[row*columns_+column]; }
};
Note that the C++ standard only allows operator[] to take a single operand, so you can't use it for this job, at least directly. In the example above, I've (obviously enough) used operator() instead, so subscripts look more like Fortran or BASIC than you're accustomed to in C++. If you're really set on using [] notation, you can do it anyway, though it's mildly tricky (you overload it in the matrix class to return a proxy, then have the proxy class also overload operator[] to return (a reference to) the correct element -- it's mildly ugly internally, but works perfectly well anyway).
Here's an example of how to implement the version using multiple overloads of operator[]. I wrote this (quite a while) before most compilers included std::vector, so it statically allocates an array instead of using a vector. It's also for the 3D case (so there are two levels of proxies involved), but with a bit of luck, the basic idea comes through anyway:
template<class T, int size>
class matrix3 {
T data[size][size][size];
friend class proxy;
friend class proxy2;
class proxy {
matrix3 &m_;
int index1_, index2_;
public:
proxy(matrix3 &m, int i1, int i2)
: m_(m), index1_(i1), index2_(i2)
{}
T &operator[](int index3) {
return m_.data[index1_][index2_][index3];
}
};
class proxy2 {
matrix3 &m_;
int index_;
public:
proxy2(matrix3 &m, int d) : m_(m), index_(d) { }
proxy operator[](int index2) {
return proxy(m_, index_, index2);
}
};
public:
proxy2 operator[](int index) {
return proxy2(*this, index);
}
};
Using this, you can address the matrix with the normal C++ syntax, such as:
matrix3<double, size> m;
for (int x=0; x<size; x++)
for (int y = 0; y<size; y++)
for (int z = 0; z<size; z++)
m[x][y][z] = x*100 + y * 10 + z;
An std::vector is normally implemented as a pointer to some dynamically allocated data, so something like a vector<vector<vector<int>>> will dereference two levels of pointers to get to each piece of data. This means more memory references, which tend to be fairly slow on most modern processors. Since each vector contains separately allocated data, it also leads to poor cache locality as a rule. It can also waste some space, since each vector stores both its allocated size and the size in use.
Boost implements matrices (supporting mathematical operations) in its uBLAS library, and provides usage syntax like the following.
#include <boost/numeric/ublas/matrix.hpp>
int main(int argc, char* argv[])
{
unsigned int N = atoi(argv[1]);
boost::matrix<int> myMatrix(N, N);
for (unsigned i = 0; i < myMatrix.size1 (); ++i)
for (unsigned j = 0; j < myMatrix.size2 (); ++j)
myMatrix(i, j) = 3 * i + j;
return 0;
}
Sample Code:
template<class T>
class Array2D
{
public:
Array2D(int a, int b)
{
num1 = (T**)new int [a*sizeof(int*)];
for(int i = 0; i < a; i++)
num1[i] = new int [b*sizeof(int)];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
num1[i][j] = i*j;
}
}
}
class Array1D
{
public:
Array1D(int* a):temp(a) {}
T& operator[](int a)
{
return temp[a];
}
T* temp;
};
T** num1;
Array1D operator[] (int a)
{
return Array1D(num1[a]);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Array2D<int> arr(20, 30);
std::cout << arr[2][3];
getchar();
return 0;
}
enter code here