头文件:
#ifndef MAIN_WTF_BAG4_H
#define MAIN_WTF_BAG4_H
#include <cstdlib>
namespace main_wtf_6
{
template<class Item>
class bag
{
public:
typedef Item value_type;
typedef std::size_t size_type;
static const size_type DEFAULT_CAPACITY = 30;
bag(size_type initial_capacity = DEFAULT_CAPACITY);
bag(const bag& source);
~bag();
void reserve(size_type new_capacity);
size_type erase(const Item& target);
bool erase_one(const Item& target);
void insert(const Item& entry);
void operator +=(const bag& addend);
void operator = (const bag& source);
size_type size() const { return used; };
size_type count(const Item& target) const;
Item getData(size_type i) const { return data[i]; };
Item grab() const;
private:
Item *data;
size_type used;
size_type capacity;
};
template<class Item>
bag<Item> operator +(const bag<Item>& b1,const bag<Item>& b2);
}
#include "bag4.template"
#endif
实现文件:
#include <algorithm>
#include<iostream>
#include <cassert>
namespace main_wtf_6
{
// const bag::size_type bag::CAPACITY;
template<class Item>
bag<Item>::bag(size_type initial_capacity)
{
data = new Item[initial_capacity];
capacity = initial_capacity;
used = 0;
}
template<class Item>
bag<Item>::~bag()
{
delete[] data;
}
template<class Item>
bag<Item>::bag(const bag<Item>& source)
{
data = new Item[source.capacity];
capacity = source.capacity;
used = source.used;
copy(source.data,source.data+used,data);
}
template<class Item>
void bag<Item>::reserve(size_type new_capacity)
{
Item *larger_array;
if(new_capacity == capacity)
return;
if(new_capacity < used)
new_capacity = used;
larger_array = new Item[new_capacity];
std::copy(data,data+used,larger_array);
delete[] data;
data = larger_array;
capacity = new_capacity;
}
template<class Item>
typename bag<Item>::size_type bag<Item>::erase(const Item& target)
{
size_type num = 0;
while(erase_one(target))
{
num++;
}
return num;
}
template<class Item>
bool bag<Item>::erase_one(const Item& target)
{
for(std::size_t i=0;i<used;i++)
{
if(target == data[i])
{
data[i] = data[used-1];
data[used-1] = 0;
used--;
return true;
}
}
return false;
}
template<class Item>
void bag<Item>::insert(const Item& entry)
{
if(used == capacity)
{
reserve(used+1);
}
data[used++] = entry;
}
template<class Item>
typename bag<Item>::size_type bag<Item>::count(const Item& target) const
{
size_type num = 0;
for(size_t i=0;i<used;i++)
{
if(target == data[i])
num++;
}
return num;
}
template<class Item>
void bag<Item>::operator+=(const bag<Item>& addend)
{
if((used+addend.size()) > capacity)
{
reserve(used+addend.size());
}
copy(addend.data,addend.data+addend.used,data+used);
used += addend.size();
/*
else
{
for(size_t i=0;i<addend.size();i++)
{
data[used++] = addend.getData(i);
}
}*/
}
template<class Item>
void bag<Item>::operator=(const bag<Item>& source)
{
Item *new_data;
if(this == &source)
return;
if(capacity != source.capacity)
{
new_data = new Item[source.capacity];
delete[] data;
data = new_data;
capacity = source.capacity;
}
used = source.used;
copy(source.data,source.data+used,data);
}
template<class Item>
Item bag<Item>::grab() const
{
size_type i;
assert(size() > 0);
i = (std::rand() % size());
return data[i];
}
template<class Item>
bag<Item> operator +(const bag<Item>& b1,const bag<Item>& b2)
{
bag bag1(b1.size()+b2.size());
bag1 += b1;
bag1 += b2;
return bag1;
}
}