Compare comp;
public:
// Don't need to call make_heap(); it's empty:
PQV(Compare cmp = Compare()) : comp(cmp) {}
void push(const T& x) {
// Put it at the end:
v.push_back(x);
// Re-adjust the heap:
push_heap(v.begin(), v.end(), comp);
}
void pop() {
// Move the top element to the last position:
pop_heap(v.begin(), v.end(), comp);
// Remove that element:
v.pop_back();
}
const T& top() { return v.front(); }
bool empty() const { return v.empty(); }
int size() const { return v.size(); }
typedef vector
TVec vector() {
TVec r(v.begin(), v.end());
// It’s already a heap
sort_heap(r.begin(), r.end(), comp);
// Put it into priority-queue order:
reverse(r.begin(), r.end());
return r;
}
};
int main() {
PQV
srand(time(0));
for(int i = 0; i < 100; i++)
pqi.push(rand() % 25);
const vector
copy(v.begin(), v.end(),
ostream_iterator
cout << "\n-----------\n";
while(!pqi.empty()) {
cout << pqi.top() << ' ';
pqi.pop();
}
} ///:~
The PQV class template follows the same form as the STL’s priority_queue, but has the additional member vector( ), which creates a new vector that’s a copy of the one in PQV (which means that it’s already a heap). It then sorts that copy (leaving PQV’s vector untouched), and reverses the order so that traversing the new vector produces the same effect as popping the elements from the priority queue.
You may observe that the approach of deriving from priority_queue used in PriorityQueue4.cpp could be used with the above technique to produce more succinct code:
//: C07:PriorityQueue8.cpp
// A more compact version of PriorityQueue7.cpp
#include
#include
#include
#include
#include
#include
using namespace std;
template
class PQV : public priority_queue
public:
typedef vector
TVec vector() {
TVec r(c.begin(), c.end());
// c is already a heap
sort_heap(r.begin(), r.end(), comp);
// Put it into priority-queue order:
reverse(r.begin(), r.end());
return r;
}
};
int main() {
PQV
srand(time(0));
for(int i = 0; i < 100; i++)
pqi.push(rand() % 25);
const vector
copy(v.begin(), v.end(),
ostream_iterator
cout << "\n-----------\n";
while(!pqi.empty()) {
cout << pqi.top() << ' ';
pqi.pop();
}
} ///:~
The brevity of this solution makes it the simplest and most desirable, plus it’s guaranteed that the user will not have a vector in the unsorted state. The only potential problem is that the vector( ) member function returns the vector
Holding bits
Because C was a language that purported to be "close to the hardware," many have found it dismaying that there was no native binary representation for numbers. Decimal, of course, and hexadecimal (tolerable only because it’s easier to group the bits in your mind), but octal? Ugh. Whenever you read specs for chips you’re trying to program, they don’t describe the chip registers in octal or even hexadecimal—they use binary. And yet C won’t let you say 0b0101101, which is the obvious solution for a language close to the hardware.
Although there’s still no native binary representation in C++, things have improved with the addition of two classes: bitset and vector
1.Each bitset holds a fixed number of bits. You establish the quantity of bits in the bitset template argument. The vector
2.The bitset template is explicitly designed for performance when manipulating bits, and is not a "regular" STL container. As such, it has no iterators. The number of bits, being a template parameter, is known at compile time and allows the underlying integral array to be stored on the runtime stack. The vector
There is no trivial conversion between a bitset and a vector
bitset
The template for bitset accepts an unsigned integral template argument that is the number of bits to represent. Thus, bitset<10> is a different type than bitset<20>, and you cannot perform comparisons, assignments, and so on between the two.