sorting vectors based on size() - c++

i have a 2-d vector like vector < vector < coordinates > > v( points); where coordinates class is:
class coordinate{
public :
int x;
int y;
coordinate(){
x=0;
y=0;
}
};
and points is 20.
how to sort the individual vectors v[i] based on v[i].size() , ie based on number of coordinates objects pushed in v[i]. ???

1) make a function that compares two vectors based on size:
bool less_vectors(const vector& a,const vector& b) {
return a.size() < b.size();
}
2) sort with it
sort(v.begin(),v.end(),less_vectors);

make a function which you can use whatever attributes to compare the objects and then use STL sort() algorithm to sort the container.
overload the < operation of that class and make it the same as the above function. Then you can use the sort() function provided by the STL containers (like STL list).

Related

Matrix multiplication via iterators help needed

So Im trying to implement an operator overload which will allows me to multiply a matrix and a vector. The matrix is itself a vector of vectors. I have produced code which achieves this through use of for-loops and simple vector indexing, however, I'd like to try implement it with iterators.
My first step was to produce an operator overload which allows me to 'multiply' vectors. In this sense multiplying is a row by row operations. So for two vectors a = {a1,a2,a3} and b = {b1,b2,b3}, the results of a*b is {a1b1, a2b2, a3b3}. This was implemented as follows:
template<typename T>
vector<double> operator*(const vector<T> &v1, const vector<T> &v2) //vector * vector [broken down matrix] Not dot product
{
vector<double> output(v2.size());
int pos = 0;
for(auto &row : v1){
for(auto &col : v2){
output[pos] = col*row;
}
pos++;
}
return output;
}
My idea was to then implement pretty much the following code for the multiplication of a matrix * vector:
template<typename T>
vector<double> operator*(const vector<vector<T> > &v1, const vector<T> &v2) //matrix * vector
{
vector<double> output(v2.size());
int pos = 0;
for(auto &row : v1){
output[pos] = row*v2;
}
pos++;
return output;
}
I think I know my problem. row is not a vector, so when I try to do row*v2, it does not make sense, nor does it used the vector * vector operator overload. So my question is, how can I make it so that the iterator operates over a vector of vectors, allowing the desired multiplication properties. Perhaps this approach is fundamentally floored, in which case I welcome any additional help. Thanks
follow up question: As seen, these are template functions. Is there a way I can declare the vector 'output' in terms of the typename T. I.e so that when integer vectors/matrices are passed into the function, integer vectors are returned, and when double vectors/matrices are passed into the function, double vectors are returned.

map comparator for pair of objects in c++

I want to use a map to count pairs of objects based on member input vectors. If there is a better data structure for this purpose, please tell me.
My program returns a list of int vectors. Each int vector is the output of a comparison between two int vectors ( a pair of int vectors). It is, however, possible, that the output of the comparison differs, though the two int vectors are the same (maybe in different order). I want to store how many different outputs (int vectors) each pair of int vectors has produced.
Assuming that I can access the int vector of my object with .inp()
Two pairs (a1,b1) and (a2,b2) should be considered equal, when (a1.inp() == a2.inp() && b2.inp() == b1.inp()) or (a1.inp() == b2.inp() and b1.inp() == a2.inp()).
This answer says:
The keys in a map a and b are equivalent by definition when neither a
< b nor b < a is true.
class SomeClass
{
vector <int> m_inputs;
public:
//constructor, setter...
vector<int> inp() {return m_inputs};
}
typedef pair < SomeClass, SomeClass > InputsPair;
typedef map < InputsPair, size_t, MyPairComparator > InputsPairCounter;
So the question is, how can I define equivalency of two pairs with a map comparator. I tried to concatenate the two vectors of a pair, but that leads to (010,1) == (01,01), which is not what I want.
struct MyPairComparator
{
bool operator() (const InputsPair & pair1, const InputsPair pair2) const
{
vector<int> itrc1 = pair1.first->inp();
vector<int> itrc2 = pair1.second->inp();
vector<int> itrc3 = pair2.first->inp();
vector<int> itrc4 = pair2.second->inp();
// ?
return itrc1 < itrc3;
}
};
I want to use a map to count pairs of input vectors. If there is a better data structure for this purpose, please tell me.
Using std::unordered_map can be considered instead due to 2 reasons:
if hash implemented properly it could be faster than std::map
you only need to implement hash and operator== instead of operator<, and operator== is trivial in this case
Details on how implement hash for std::vector can be found here. In your case possible solution could be to join both vectors into one, sort it and then use that method to calculate the hash. This is straightforward solution, but can produce to many hash collisions and lead to worse performance. To suggest better alternative would require knowledge of the data used.
As I understand, you want:
struct MyPairComparator
{
bool operator() (const InputsPair& lhs, const InputsPair pair2) const
{
return std::minmax(std::get<0>(lhs), std::get<1>(lhs))
< std::minmax(std::get<0>(rhs), std::get<1>(rhs));
}
};
we order the pair {a, b} so that a < b, then we use regular comparison.

std::vector making struct sort slow? c++

I have a list of structs that I am sorting by one of the members. I am using std::sort with my own comparison function, that part is fine. However, I notice a (very) large performance gap when I change the struct from:
struct square
{
float x;
float y;
float z;
float scale;
float angle;
GLuint texture;
};
to
struct square
{
float x;
float y;
float z;
float scale;
float angle;
GLuint texture;
std::vector <float> color;
};
I have since used an entirely different method, and I realize that using a vector like this is a bad idea (I know the size of array - rgb) but I was wondering why I got the performance hit. I was comparing the z values to sort.
Here is my sorting function and struct list:
std::vector <square> square_list;
//Then add a bunch of squares
bool sort (square a,square b)
{
return a.z < b.z;
}
//Here is the sort that is slow
std::sort (square_list.begin(),square_list.end(),sort);
I wonder if it has anything to do with re-ordering the list of structs as their size is significantly bigger in the second case?
Thanks for any responses.
bool sort (square a,square b)
This copies the structs each time, including the vectors. Vectors are slower to copy than normal arrays. You should use this instead.
bool sort (const square& a, const square& b)
If you are using C++11, you can replace the vector with std::array as the size is constant.
In addition to take parameters as const ref you could use a functor for comparison. That is often faster because functors are more easy to inline.
std::vector <square> square_list;
//Then add a bunch of squares
struct sort
{
bool operator() (const square& a, const square& b) const {
return a.z < b.z;
}
}
std::sort (square_list.begin(),square_list.end(),sort);
sort copy your values every time and std::vector preallocate a bunch of memory. The amount of copy time is bigger
Did you try storing pointers instead of the whole struct in your vector?
std::vector <square*> square_list;
//Then add a bunch of squares
bool sort (square* a,square* b)
{
return a->z < b->z;
}
//Here is the sort that is slow
std::sort (square_list.begin(),square_list.end(),sort);

dot product of vector < vector < int > > over the first dimension

I have
vector < vector < int > > data_mat ( 3, vector < int > (4) );
vector < int > data_vec ( 3 );
where data_mat can be thought of as a matrix and data_vec as a column vector, and I'm looking for a way to compute the inner product of every column of data_mat with data_vec, and store it in another vector < int > data_out (4).
The example http://liveworkspace.org/code/2bW3X5%241 using for_each and transform, can be used to compute column sums of a matrix:
sum=vector<int> (data_mat[0].size());
for_each(data_mat.begin(), data_mat.end(),
[&](const std::vector<int>& c) {
std::transform(c.begin(), c.end(), sum.begin(), sum.begin(),
[](int d1, double d2)
{ return d1 + d2; }
);
}
);
Is it possible, in a similar way (or in a slightly different way that uses STL functions), to compute column dot products of matrix columns with a vector?
The problem is that the 'd2 = d1 + d2' trick does not work here in the column inner product case -- if there is a way to include a d3 as well that would solve it ( d3 = d3 + d1 * d2 ) but ternary functions do not seem to exist in transform.
In fact you can use your existing column sum approach nearly one to one. You don't need a ternary std::transform as inner loop because the factor you scale the matrix rows with before summing them up is constant for each row, since it is the row value from the column vector and that iterates together with the matrix rows and thus the outer std::for_each.
So what we need to do is iterate over the rows of the matrix and multiply each complete row by the corresponding value in the column vector and add that scaled row to the sum vector. But unfortunately for this we would need a std::for_each function that simultaneously iterates over two ranges, the rows of the matrix and the rows of the column vector. To achieve this, we could use the usual unary std::for_each and just do the iteration over the column vector manually, using an additional iterator:
std::vector<int> sum(data_mat[0].size());
auto vec_iter = data_vec.begin();
std::for_each(data_mat.begin(), data_mat.end(),
[&](const std::vector<int>& row) {
int vec_value = *vec_iter++; //manually advance vector row
std::transform(row.begin(), row.end(), sum.begin(), sum.begin(),
[=](int a, int b) { return a*vec_value + b; });
});
The additional manual iteration inside the std::for_each isn't really that idiomatic use of the standard library algorithms, but unfortunately there is no binary std::for_each we could use.
Another option would be to use std::transform as outer loop (which can iterate over two ranges), but we don't really compute a single value in each outer iteration to return, so we would have to just return some dummy value from the outer lambda and throw it away by using some kind of dummy output iterator. That wouldn't be the cleanest solution either:
//output iterator that just discards any output
struct discard_iterator : std::iterator<std::output_iterator_tag,
void, void, void, void>
{
discard_iterator& operator*() { return *this; }
discard_iterator& operator++() { return *this; }
discard_iterator& operator++(int) { return *this; }
template<typename T> discard_iterator& operator=(T&&) { return *this; }
};
//iterate over rows of matrix and vector, misusing transform as binary for_each
std::vector<int> sum(data_mat[0].size());
std::transform(data_mat.begin(), data_mat.end(),
data_vec.begin(), discard_iterator(),
[&](const std::vector<int>& row, int vec_value) {
return std::transform(row.begin(), row.end(),
sum.begin(), sum.begin(),
[=](int a, int b) {
return a*vec_value + b;
});
});
EDIT: Although this has already been discussed in comments and I understand (and appreciate) the theoretic nature of the question, I will still include the suggestion that in practice a dynamic array of dynamic arrays is an awfull way to represent such a structurally well-defined 2D array like a matrix. A proper matrix data structure (which stores its contents contigously) with the appropriate operators is nearly always a better choice. But nevertheless due to their genericity you can still use the standard library algorithms for working with such a custom datastructure (maybe even by letting the matrix type provide its own iterators).

Out of four std::vector objects select the one with the most elements

I have four std::vector containers that all might (or might not) contain elements. I want to determine which of them has the most elements and use it subsequently.
I tried to create a std::map with their respective sizes as keys and references to those containers as values. Then I applied std::max on the size() of each vector to figure out the maximum and accessed it through the std::map.
Obviously, this gets me into trouble once there is the same number of elements in at least two vectors.
Can anyone think of a elegant solution ?
You're severely overthinking this. You've only got four vectors. You can determine the largest vector using 3 comparisons. Just do that:
std::vector<blah>& max = vector1;
if (max.size() < vector2.size()) max = vector2;
if (max.size() < vector3.size()) max = vector3;
if (max.size() < vector4.size()) max = vector4;
EDIT:
Now with pointers!
EDIT (280Z28):
Now with references! :)
EDIT:
The version with references won't work. Pavel Minaev explains it nicely in the comments:
That's correct, the code use
references. The first line, which
declares max, doesn't cause a copy.
However, all following lines do cause
a copy, because when you write max =
vectorN, if max is a reference, it
doesn't cause the reference to refer
to a different vector (a reference
cannot be changed to refer to a
different object once initialized).
Instead, it is the same as
max.operator=(vectorN), which simply
causes vector1 to be cleared and
replaced by elements contained in
vectorN, copying them.
The pointer version is likely your best bet: it's quick, low-cost, and simple.
std::vector<blah> * max = &vector1;
if (max->size() < vector2.size()) max = &vector2;
if (max->size() < vector3.size()) max = &vector3;
if (max->size() < vector4.size()) max = &vector4;
Here's one solution (aside from Pesto's far-too-straightforward approach) - I've avoided bind and C++0x lambdas for explanatory purposes, but you could use them to remove the need for a separate function. I'm also assuming that with two vectors with an equal number of elements, which one is picked is irrelevant.
template <typename T> bool size_less (const T* lhs, const T* rhs) {
return lhs->size() < rhs ->size();
}
void foo () {
vector<T>* vecs[] = {&vec1, &vec2, &vec3, &vec4};
vector<T>& vec = std::min_element(vecs, vecs + 4, size_less<vector<T> >);
}
Here is my very simple method. Only interest is that you just need basic c++ to understand it.
vector<T>* v[] = {&v1, &v2, &v3, &v4}, *max=&v1;
for(int i=1; i < 4; ++i)
if (v[i]->size() > max->size()) max = v[i];
This is a modified version of coppro's answer using a std::vector to reference any number of vectors for comparison.
template <typename T> bool size_less (const T* lhs, const T* rhs) {
return lhs->size() < rhs ->size();
}
void foo () {
// Define vector holding pointers to the original vectors
typedef vector< vector<T>* > VectorPointers;
// Fill the list
VectorPointers vecs;
vecs.push_back(&vec1);
vecs.push_back(&vec2);
vecs.push_back(&vec3);
vecs.push_back(&vec4);
vector<T>& vec = std::min_element(
vecs.begin(),
vecs.end(),
size_less<vector<T> >
);
}
I'm all for over-thinking stuff :)
For the general problem of finding the highest/lowest element in a group, I would use a priority_queue with a comparator:
(copying shamelessly from coppro, and modifying...)
template <typename T> bool size_less (const T* lhs, const T* rhs)
{
return lhs->size() < rhs ->size();
}
vector* highest()
{
priority_queue<vector<T>, size_less<T> > myQueue;
...
...
return myQueue.top();
}
You could use a std::multimap. That allows multiple entries with the same key.