A little hard to phrase in a question so I will use an example. Lets say I do:
generate(myvec.begin(), myvec.end(), func())
Can I have it so that func() can read the index that generate is up to such that:
int func()
{
if(index<2)
return 1;
else
return 2;
}
such that myvec[0]=1, myvec[1]=1, myvec[2]=2, myvec[3]=2,..., myvec[N]=2?
The short answer is "no, not directly". It can create its own variable that should track with the index, but (in a case like this) there's simply no access to the index itself.
Under the circumstances, I'd almost certainly just use std::fill twice:
std::fill_n(myVec.begin(), 2, 1);
std::fill(myVec.begin()+2, myVec.end(), 2);
Shorter, and simpler.
Yes, if you use a function object as the generator (as juan points out, it is questionable whether this solution is guaranteed to work by the standard! Exercise caution and use Jerry's method.):
class mygenerator {
public:
mygenerator() : hits(0) {}
int operator()() {
hits++;
return (hits <= 2 ? 1 : 2);
}
private:
int hits;
}
...
mygenerator mg1;
std::generate(myvec.begin(), myvec.end(), mg1);
class funkygen
{
int index;
public:
funkygen()
: index(0)
{ }
int operator()()
{
if(t < 2)
t++;
return t;
}
};
/* other code */
funkygen f;
std::generate(myvec.begin(), myvec.end(), f);
As juanchopanza pointed out in a comment on another answer, the elements of vec are not guaranteed to be accessed in a particular sequential order. The only guarantee is that every item will be accessed exactly once.
Related
I'm solving a problem with the segment tree. It has got a very strict memory limit, so I don't want to use extra n memory for remembering information about single segments and return it from the array I built the tree from.
...
struct SegTree {
vector<int>* singleElements;
vector<int> tree;
SegTree() : singleElements(nullptr) {}
SegTree(vector<int>* arr) : singleElements(arr) {
tree.resize(arr.size() - 1);
build(...);
}
...
}
int main() {
vector<int> a(10, 1), b(10, -1);
SegTree st1(a);
SegTree st2();
st2.assign(b);
return 0;
}
I am not sure with this part of c++. Sorry for my bad English.
You should use moving constructor rather than copying one.
SegTree(std::vector<int> && arr);
And call it in this way:
SegTree st1(std::move(a));
Notice!
After this the 'a' vector is in unspecified state, so you cannot operate on it.
Take a look at the documetation!
cpp documentation
i want to implement a container, which contains maximal 20 Solutions.
If the container contains 20 Solutions any Solution that is added is only accepted if its
1) new_value < worst value in the Container
2) if new_value is already in the container (and 1) holds) then memcmp(new_assignment, assigment, assignment_size) != 0
Then the worst solutions is deleted. (Including the int array)
the assignment_size is for all Solutions the same.
struct Solution {
double value;
int *assignment;
int assigment_size;
};
What is the easiest way to implement this structure? Can you use some container of the STL?
Ok Thank you.
I hope it is correct. It tried to keep the list trough insert sorted so it is easier to check and then you can remove the last element.
struct Solution {
double power_peak;
int *assignment;
int size;
~Solution() { delete[] assignment; }
};
class Container {
list<Solution> Solutions;
uint max_size;
double worst_solution;
public:
Container (uint size)
{
max_size = size;
}
void addSolution(Solution s)
{
list<Solution>::iterator insert_position = Solutions.begin();
while (insert_position != Solutions.end() && (*insert_position).power_peak < s.power_peak)
{
if ((*insert_position).power_peak == s.power_peak && memcmp((*insert_position).assignment, s.assignment, s.size) == 0)
{
return;
}
++insert_position;
}
Solutions.insert(insert_position, s);
if (Solutions.size() > max_size)
{
Solutions.pop_back();
}
worst_solution = (*(--(Solutions.end())))->power_peak;
}
double getWorst()
{
return worst_solution;
}
};
Note: I assumed that your solution is described by the Solution structure you posted.
The easiest solution would be a std::array<Solution, 20>, wrapped in a custom container wrapper.
You should have something like this:
class SolutionsSequence
{
public:
// in a function to add a solution to the sequence, you should
// implement the criteria to decide which solution is worse
private:
std::array<Solution, 20> solutions_;
};
Other than that, you should not use memcpy in C++. Consider using std::copy, or std::copy_n instead.
Also consider using a std::vector for assignments, and then you can get rid of the assignment_size.
I have my loop going through vector's elements. While in this loop some of the elements are being (I want them to be) removed. Although std::vector does not allow to do this, and I would like an alternative.
for(unsigned int j = 0; j < rectArray.size(); j++)
{
if( rectArray[j] == 2 )
{
rectArray.erase(rectArray.begin() + j);
}
//...
}
Do you think a std::list would be good here ? Can I use something else ?
Unless the elements of the vector are very expensive to copy, the simplest is probably to std::copy_if (or otherwise copy the ones you want to keep) into a new vector, and then swap that with the original. There's also remove_if followed by resize.
If the elements are very expensive to relocate, then a list would avoid that, but it depends what else you do with the collection. If you do something else that would be cripplingly slow with a list, then you've just moved the problem elsewhere.
I would suggest modifying your code such that it uses iterators instead of the actual vector. It's much cleaner and more efficient like this:
for (auto it = rectArray.begin(); it != rectArray.end(); ++it)
{
// Access the current element with *it
// If you want you can pass `it` and `rectArray.end()` as
// the lower and upper bounds of the new collection,
// rather than doing expensive resizes of the vector.
}
Note that auto is a C++11 feature (the way I used it). If your compiler supports that you might also want to use C++11's foreach:
for (auto it : rectArray) {
// same as before
}
Removing an element from the middle of a vector is expensive - because you have to move all the later elements down.
If you need to add/remove elements to the middle of a container then a list is generally better.
List would be better than a vector - as it will not cost you anything to remove elements from the middle of the list. Removing elements from the middle of a vector, on the other hand, has linear complexity.
Possible alternative to std::remove_if. A bit faster and doesn't require a functor, however it does not maintain order.
auto end = std::end(rectArray);
for(auto it = std::begin(rectArray); it != end; ++it)
{
if(it->remove_me()))
std::swap(*it, *--end); // or even faster *it = std::move(*--end);
}
rectArray.erase(end, std::end(rectArray));
If you are doing a lot of deletes, a list is probably the way to go. Here is some sample code to help.
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
class Widget
{
public:
explicit Widget(int someNumber);
bool ShouldDelete();
bool ShouldDeleteComplex(int a, int b, int c);
private:
int _someNumber;
};
Widget::Widget(int someNumber) : _someNumber(someNumber)
{
}
bool Widget::ShouldDelete()
{
if (_someNumber > 2)
{
return true;
}
return false;
}
bool Widget::ShouldDeleteComplex(int a, int b, int c)
{
if ((a * b - c) > _someNumber)
{
return true;
}
return false;
}
int main()
{
list<Widget> lw;
lw.push_back(Widget(1));
lw.push_back(Widget(2));
lw.push_back(Widget(3));
// delete from list using functor
lw.remove_if(mem_fun_ref(&Widget::ShouldDelete));
// delete from list using lambda function
lw.remove_if([] (Widget& x) { return x.ShouldDeleteComplex(1, 2, 0); } );
vector<Widget> vw;
vw.push_back(Widget(1));
vw.push_back(Widget(2));
vw.push_back(Widget(3));
// delete using functor
vw.erase(remove_if(vw.begin(), vw.end(), mem_fun_ref(&Widget::ShouldDelete)), vw.end());
// delete using lambda function
vw.erase(
remove_if(vw.begin(), vw.end(),
[] (Widget& x) { return x.ShouldDeleteComplex(1, 2, 0); }
),
vw.end());
return 0;
}
I have the following C++ code:
Some_class * temp1 = findTemp1(...); // returns NULL or a valid pointer
Some_class * temp2 = findTemp2(...); // returns NULL or a valid pointer
Some_class * temp3 = findTemp3(...); // returns NULL or a valid pointer
Now I would like to count how many of these returned a valid pointer (0, 1, 2 or 3).
The only way I can think of is just to test them one by one:
int count = 0;
if (temp1)
count++;
if (temp2)
count++;
if (temp3)
count++;
For 3 pointers, it's not too bad, but it doesn't scale well. Is there a more efficient way assuming I don't redefine the findTempN funcitons (to maybe pass in the counter)?
Thanks a lot for your quick replies! No, I am not going to change the code, I was just wondering what were my other options. I also realized that I cannot be asking for something "scalable" if I am using distinct literals like that to define the 3 pointers. Of course, I didn't think of the things you replied :)
Well, since this is C++ we can go crazy in the quest for terseness... for example:
int count = !!temp1 + !!temp2 + !!temp3;
Update: I probably owe Ivan an explanation of what's going on here.
Assuming temp is any kind of pointer, !temp forces the coercion of the pointer's value to bool (we want to do this) and negates the result (this is a side effect that we do not want). This results in true if the pointer is null and false if the pointer is not null, which is the opposite of what we 'd like. So we add another ! in front to negate the result again.
This leaves us with adding three bool values which coerces them to int and performs the addition, whereupon we have our final result.
You might find it easier to understand the completely equivalent
int count = (bool)temp1 + (bool)temp2 + (bool)temp3;
which I did not use because typing !! is three characters shorter than (bool) (note: you might think that this is a nice trick, but when writing code it is a really bad idea to make decisions based on how many characters you have to type).
The moral of the story is that doing this type of thing can be called either clever or atrocious, depending on who you ask -- but in C++ there has traditionally been high tolerance for atrocities.
Note that if the pointers were in some type of collection to begin with, you could write much better-looking code using std::count_if, e.g.:
bool isNotNull(void* ptr) {
return ptr != 0;
}
std::vector<Some_class*> vec;
vec.push_back(temp1);
vec.push_back(temp2);
vec.push_back(temp3);
int count = std::count_if(vec.begin(), vec.end(), isNotNull);
See it in action.
Or, as very cleverly suggested by MSalters in the comments, you can lose the isNotNull function by counting the pointers which are 0 and subtracting this from the number of all pointers -- but for this, you will need to somehow know what this number is (easy if they are in a vector):
int count = vec.size() - std::count(vec.begin(), vec.end(), 0);
See it in action.
#define N 3
typedef Some_class *PointerGenerator(...);
PointerGenerator funcs[N];
func[0] = &findTemp1;
func[1] = &findTemp2;
func[2] = &findTemp3;
Some_class *ptrs[N];
for(size_t i = 0; i < N; ++i) ptrs[i] = func[i]();
for(size_t i = 0; i < N; ++i) { if(ptrs[i]) ++count; }
C++0x variant:
int count = std::count_if(ptrs, ptrs + N, [](const Some_class *i) -> bool { return i != NULL; } );
The code you have is Good Enough, don't mess with it.
Introducing subtlety is a common novice error, don't do it.
That said, NULL is a valid pointer value, and you can do e.g. count += !!temp1 + !!temp2 + !!temp3 (but that would be newbie obfuscation, do not actually do that).
Cheers & hth.,
If all of the pointers are the same type, put the pointers in a table,
or if you can't do that, make a table of pointers to the pointers. Then
use std::count or std::count_if. Something like:
SomeClass** pointerTable[] =
{
&temp1,
&temp2,
&temp3,
// ...
};
struct IndirectIsNoNull
{
bool operator()( SomeClass** p ) const
{
return *p != NULL;
}
};
// ...
int validPointerCount = std::count_if( begin( pointerTable ),
end( pointerTable ),
IndirectIsNoNull() );
Introduce a static counter.
template<typename T>
struct ValidPointer
{
static unsigned int count;
};
template<typename T>
unsigned int ValidPointer<T>::count = 0;
template<typename T>
static void isValid (const T* const p)
{
if(p)
ValidPointer<T*>::count++;
}
Usage:
isValid(temp1);
isValid(temp2);
...
At any point of time, if you want to retrieve then,
unsigned int count = ValidPointer<Some_class*>::count;
This code can be improved as per your requirement.
Do you need the pointers afterwards? temp suggests otherwise. In that case, you can eliminate those:
int count = 0;
if (findTemp1())
count++;
if (findTemp2())
count++;
if (findTemp3())
count++;
Hide the counter in a class:
class Some_class {};
typedef Some_class* (*FindFunction_t)();
Some_class* findTemp1() {return NULL;}
Some_class* findTemp2() {return new Some_class;}
Some_class* findTemp3() {return new Some_class;}
class Finder
{
public:
Finder() : count_(0) {}
Some_class* CallAndCount(FindFunction_t fn) {return Count(fn());}
int GetCount() const {return count_;}
private:
Some_class* Count(Some_class* p) {if(p) count_++; return p;}
int count_;
};
int main()
{
Finder f;
Some_class* temp1 = f.CallAndCount(findTemp1);
Some_class* temp2 = f.CallAndCount(findTemp2);
Some_class* temp3 = f.CallAndCount(findTemp3);
std::wcout << f.GetCount() << L"\n";
}
The names aren't the best and there are memory leaks but you should get the idea.
I think this meets your objective of scalability although you would need to add template functions if your find functions were to take parameters
I would like to do something like this (I'm aware that this won't compile):
struct Container{
vector<int> storage;
};
float foo(Container* aContainer){
if(aContainer!=NULL)
vector<int>& workingStorage=aContainer->storage;
else
vector<int> workingStorage;
workingStorage.reserve(1000000);
....use workingStorage to calculate something......
return calculated_result;
}
So - if i pass a Container to the function, i want that the function uses the vector in the container to work with instead of a local variable. If no container is provided, it should use a local variable.
of course I could just in the end of the function copy the local variable to the storage of the Container, but that's not what I want to do.
Thanks!
Create a local std::vector<int> named local_storage for the case where a container is not provided by the caller, then create a reference to whatever container you are actually going to use.
std::vector<int> local_storage;
std::vector<int>& working_storage = aContainer
? aContainer->storage
: local_storage;
One way to approach this problem is to break the function foo into 2 functions
float foo(Container* aContainer){
if(aContainer!=NULL) {
return foo_core(aContainer->storage);
} else {
vector<int> workingStorage;
return foo_core(workingStorage);
}
float foo_core(vector<int>& workingStorage) {
...
// rest of original foo
}
vector<int> temp;
vector<int>& workingStorage = (aContainer!=NULL) ? aContainer->storage : temp;
The design is apparently horrible. But given that an optional externally provided storage is what you want, JaredPar (his answer) has a good idea. Cleaning that further up:
struct Container
{
vector<int> storage;
};
double foo( vector<int>& workingStorage )
{
workingStorage.reserve( 1000000 );
//....use workingStorage to calculate something......
return calculated_result;
}
double foo( Container& storageProvider )
{
return foo( storageProvider.storage );
}
double foo()
{
vector<int> storage;
return foo( storage );
}
Cheers & hth.,
Why don't you make sure that aContainer->storage is initialized before you pass aContainer it to foo. That makes your code lot more neater. Have an assert statement at the start of the function to check aContainer->storage for NULL.