整理的算法模板合集: ACM模板
最近使用到一个c++的容器——unordered_map
,它是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能。
unordered_map
内部其实是由很多哈希桶组成的,每个哈希桶中可能没有元素,也可能有多个元素。template < class Key, // unordered_map::key_type
class T, // unordered_map::mapped_type
class Hash = hash<Key>, // unordered_map::hasher
class Pred = equal_to<Key>, // unordered_map::key_equal
class Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type
> class unordered_map;
主要使用的也是模板的前2个参数<键,值>(需要更多的介绍可以点击这里)
unordered_map<const Key, T> map;
unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值。
unordered_map<Key,T>::iterator it;
(*it).first; // the key value (of type Key)
(*it).second; // the mapped value (of type T)
(*it); // the "element value" (of type pair)
它的键值分别是迭代器的first和second属性。
it->first; // same as (*it).first (the key value)
it->second; // same as (*it).second (the mapped value)
unordered_map的构造方式有几种:
3.1.2示例代码
// constructing unordered_maps
#include
#include
#include
using namespace std;
typedef unordered_map<string,string> stringmap;
stringmap merge (stringmap a,stringmap b) {
stringmap temp(a); temp.insert(b.begin(),b.end()); return temp;
}
int main ()
{
stringmap first; // 空
stringmap second ( {
{
"apple","red"},{
"lemon","yellow"}} ); // 用数组初始
stringmap third ( {
{
"orange","orange"},{
"strawberry","red"}} ); // 用数组初始
stringmap fourth (second); // 复制初始化
stringmap fifth (merge(third,fourth)); // 移动初始化
stringmap sixth (fifth.begin(),fifth.end()); // 范围初始化
cout << "sixth contains:";
for (auto& x: sixth) cout << " " << x.first << ":" << x.second;
cout << endl;
return 0;
}
输出结果:
sixth contains: apple:red lemon:yellow orange:orange strawberry:red
size_type size() const noexcept;
返回unordered_map的大小
bool empty() const noexcept;
iterator find ( const key_type& k );
查找key所在的元素。
插入有几种方式:
具体的例子可以看后面示例代码。
mapped_type& at ( const key_type& k );
查找key所对应的值
mymap.at(“Mars”) = 3396; //mymap[“Mars”] = 3396
擦除元素也有几种方式:
通过位置(迭代器)
iterator erase ( const_iterator position );
通过key
size_type erase ( const key_type& k );
通过范围(两个迭代器)
iterator erase ( const_iterator first, const_iterator last );
void clear() noexcept
清空unordered_map
void swap ( unordered_map& ump );
交换两个unordered_map(注意,不是交换特定元素,是整个交换两个map中的所有元素)
// unordered_map::insert
#include
#include
#include
using namespace std;
void display(unordered_map<string,double> myrecipe,string str)
{
cout << str << endl;
for (auto& x: myrecipe)
cout << x.first << ": " << x.second << endl;
cout << endl;
}
int main ()
{
unordered_map<string,double>
myrecipe,
mypantry = {
{
"milk",2.0},{
"flour",1.5}};
/****************插入*****************/
pair<string,double> myshopping ("baking powder",0.3);
myrecipe.insert (myshopping); // 复制插入
myrecipe.insert (make_pair<string,double>("eggs",6.0)); // 移动插入
myrecipe.insert (mypantry.begin(), mypantry.end()); // 范围插入
myrecipe.insert ({
{
"sugar",0.8},{
"salt",0.1}}); // 初始化数组插入(可以用二维一次插入多个元素,也可以用一维插入一个元素)
myrecipe["coffee"] = 10.0; //数组形式插入
display(myrecipe,"myrecipe contains:");
/****************查找*****************/
unordered_map<string,double>::const_iterator got = myrecipe.find ("coffee");
if ( got == myrecipe.end() )
cout << "not found";
else
cout << "found "<<got->first << " is " << got->second<<"\n\n";
/****************修改*****************/
myrecipe.at("coffee") = 9.0;
myrecipe["milk"] = 3.0;
display(myrecipe,"After modify myrecipe contains:");
/****************擦除*****************/
myrecipe.erase(myrecipe.begin()); //通过位置
myrecipe.erase("milk"); //通过key
display(myrecipe,"After erase myrecipe contains:");
/****************交换*****************/
myrecipe.swap(mypantry);
display(myrecipe,"After swap with mypantry, myrecipe contains:");
/****************清空*****************/
myrecipe.clear();
display(myrecipe,"After clear, myrecipe contains:");
return 0;
}
输出结果:
myrecipe contains:
salt: 0.1
milk: 2
flour: 1.5
coffee: 10
eggs: 6
sugar: 0.8
baking powder: 0.3
found coffee is 10
After modify myrecipe contains:
salt: 0.1
milk: 3
flour: 1.5
coffee: 9
eggs: 6
sugar: 0.8
baking powder: 0.3
After erase myrecipe contains:
flour: 1.5
coffee: 9
eggs: 6
sugar: 0.8
baking powder: 0.3
After swap with mypantry, myrecipe contains:
flour: 1.5
milk: 2
After clear, myrecipe contains:
3.4 迭代器和bucket操作
3.4.1 begin
iterator begin() noexcept;
local_iterator begin ( size_type n );
begin() : 返回开始的迭代器(和你的输入顺序没关系,因为它的无序的)
begin(int n) : 返回n号bucket的第一个迭代器
3.4.2 end
iterator end() noexcept;
local_iterator end( size_type n );
end(): 返回结束位置的迭代器
end(int n) : 返回n号bucket的最后一个迭代器
3.4.3 bucket
size_type bucket ( const key_type& k ) const;
返回通过哈希计算key所在的bucket(注意:这里仅仅做哈希计算确定bucket,并不保证key一定存在bucket中!)
3.4.4 bucket_count
size_type bucket_count() const noexcept;
返回bucket的总数
3.4.5 bucket_size
size_type bucket_size ( size_type n ) const;
返回第i个bucket的大小(这个位置的桶子里有几个元素,注意:函数不会判断n是否在count范围内)
3.4.6 示例代码
// unordered_map::bucket_count
#include
#include
#include
using namespace std;
int main ()
{
unordered_map<string,string> mymap =
{
{
"house","maison"},
{
"apple","pomme"},
{
"tree","arbre"},
{
"book","livre"},
{
"door","porte"},
{
"grapefruit","pamplemousse"}
};
/************begin和end迭代器***************/
cout << "mymap contains:";
for ( auto it = mymap.begin(); it != mymap.end(); ++it )
cout << " " << it->first << ":" << it->second;
cout << endl;
/************bucket操作***************/
unsigned n = mymap.bucket_count();
cout << "mymap has " << n << " buckets.\n";
for (unsigned i=0; i<n; ++i)
{
cout << "bucket #" << i << "'s size:"<<mymap.bucket_size(i)<<" contains: ";
for (auto it = mymap.begin(i); it!=mymap.end(i); ++it)
cout << "[" << it->first << ":" << it->second << "] ";
cout << "\n";
}
cout <<"\nkey:'apple' is in bucket #" << mymap.bucket("apple") <<endl;
cout <<"\nkey:'computer' is in bucket #" << mymap.bucket("computer") <<endl;
return 0;
}
输出结果:
mymap contains: door:porte grapefruit:pamplemousse tree:arbre apple:pomme book:livre house:maison
mymap has 7 buckets.
bucket #0's size:2 contains: [book:livre] [house:maison]
bucket #1's size:0 contains:
bucket #2's size:0 contains:
bucket #3's size:2 contains: [grapefruit:pamplemousse] [tree:arbre]
bucket #4's size:0 contains:
bucket #5's size:1 contains: [apple:pomme]
bucket #6's size:1 contains: [door:porte]
key:'apple' is in bucket #5
key:'computer' is in bucket #6
最后
unordered_map
常用的功能函数介绍就这么多了,还有一些比较不常用的功能的介绍,可以参考这里