_STL使用技巧_(不定時更新)
1 關於取整的函式
座標 math
用法:
ceil(x)返回不小於x的最小整數值(然後轉換為double型)。
floor(x)返回不大於x的最大整數值。
round(x)返回x的四捨五入整數值。
給個例子test.c:
[cpp] view plain copy
#include <stdio.h>
#include <math.h>
int main(int argc, const char *argv[]) {
float num = 1.4999;
printf("ceil(%f) is %f\n", num, ceil(num));
printf ("floor(%f) is %f\n", num, floor(num));
printf("round(%f) is %f\n", num, round(num));
return 0;
}
2 list
因此在實際使用時,如何選擇這三個容器中哪一個,應根據你的需要而定,具體可以遵循下面的原則:
1. 如果你需要高效的隨即存取,而不在乎插入和刪除的效率,使用vector
2. 如果你需要大量的插入和刪除,而不關心隨即存取,則應使用list
3. 如果你需要隨即存取,而且關心兩端資料的插入和刪除,則應使用deque。
2.list中常用的函式
2.1list中的建構函式:
list() 宣告一個空列表;
list(n) 宣告一個有n個元素的列表,每個元素都是由其預設建構函式T()構造出來的
list(n,val) 宣告一個由n個元素的列表,每個元素都是由其複製建構函式T(val)得來的
list(n,val) 宣告一個和上面一樣的列表
list(first,last) 宣告一個列表,其元素的初始值來源於由區間所指定的序列中的元素
2.2 begin()和end():通過呼叫list容器的成員函式begin()得到一個指向容器起始位置的iterator,可以呼叫list容器的 end() 函式來得到list末端下一位置,相當於:int a[n]中的第n+1個位置a[n],實際上是不存在的,不能訪問,經常作為迴圈結束判斷結束條件使用。
2.3 push_back() 和push_front():使用list的成員函式push_back和push_front插入一個元素到list中。其中push_back()從list的末端插入,而 push_front()實現的從list的頭部插入。
2.4 empty():利用empty() 判斷list是否為空。
2.5 resize(): 如果呼叫resize(n)將list的長度改為只容納n個元素,超出的元素將被刪除,如果需要擴充套件那麼呼叫預設建構函式T()將元素加到list末端。如果呼叫resize(n,val),則擴充套件元素要呼叫建構函式T(val)函式進行元素構造,其餘部分相同。
2.6 clear(): 清空list中的所有元素。
2.7 front()和back(): 通過front()可以獲得list容器中的頭部元素,通過back()可以獲得list容器的最後一個元素。但是有一點要注意,就是list中元素是空的時候,這時候呼叫front()和back()會發生什麼呢?實際上會發生不能正常讀取資料的情況,但是這並不報錯,那我們程式設計序時就要注意了,個人覺得在使用之前最好先呼叫empty()函式判斷list是否為空。
2.8 pop_back和pop_front():通過刪除最後一個元素,通過pop_front()刪除第一個元素;序列必須不為空,如果當list為空的時候呼叫pop_back()和pop_front()會使程式崩掉。
2.9 assign():具體和vector中的操作類似,也是有兩種情況,第一種是:l1.assign(n,val)將 l1中元素變為n個T(val)。第二種情況是:l1.assign(l2.begin(),l2.end())將l2中的從l2.begin()到l2.end()之間的數值賦值給l1。
2.10 swap():交換兩個連結串列(兩個過載),一個是l1.swap(l2); 另外一個是swap(l1,l2),都可能完成連個連結串列的交換。
2.11 reverse():通過reverse()完成list的逆置。
2.12 merge():合併兩個連結串列並使之預設升序(也可改),l1.merge(l2,greater()); 呼叫結束後l2變為空,l1中元素包含原來l1 和 l2中的元素,並且排好序,升序。其實預設是升序,greater()可以省略,另外greater()是可以變的,也可以不按升序排列。
#include <iostream>
2 #include <list>
3
4 using namespace std;
5
6 int main()
7 {
8 list<int> l1;
9 list<int> l2(2,0);
10 list<int>::iterator iter;
11 l1.push_back(1);
12 l1.push_back(2);
13 l2.push_back(3);
14 l1.merge(l2,greater<int>());//合併後升序排列,實際上預設就是升序
15 for(iter = l1.begin() ; iter != l1.end() ; iter++)
16 {
17 cout<<*iter<<" ";
18 }
19 cout<<endl<<endl;
20 if(l2.empty())
21 {
22 cout<<"l2 變為空 !!";
23 }
24 cout<<endl<<endl;
25 return 0;
26 }
2.13 insert():在指定位置插入一個或多個元素(三個過載):
l1.insert(l1.begin(),100); 在l1的開始位置插入100。
l1.insert(l1.begin(),2,200); 在l1的開始位置插入2個100。
l1.insert(l1.begin(),l2.begin(),l2.end());在l1的開始位置插入l2的從開始到結束的所有位置的元素。
2.14 erase():刪除一個元素或一個區域的元素(兩個過載)
l1.erase(l1.begin()); 將l1的第一個元素刪除。
l1.erase(l1.begin(),l1.end()); 將l1的從begin()到end()之間的元素刪除。
(2017.9.4更)
**優先佇列的排序寫法
(每次寫都tm查,氣死勞資了,勞資要背下來!!)
1 普通寫法(每次彈最小的)
priority_queue<int>qu;
2 對入隊的元素預設按照從大到小排序。
2018.5.15
優先佇列和set的排序方式都有這麼多種。
1 過載<運算子(你為我為啥不能過載>,我也不清楚qwq,內部就是醬紫實現的)
總共有三種寫法,常規版,外接版,this指標帥氣版
2 用仿函式(那個不是過載‘()’運算子啊親qwq)
3 記住一點,set是正常的辣個順序,而優先佇列是相反的。。恩呢
1 普通版本
#include <iostream>
#include <bits/stdc++.h>
/* 1 pair也能過載吧。可以噠
2 優先佇列和set是相反的
3 一種策略是用仿函式(雖然他也很像過載),另一種是過載運算子。
*/
using namespace std;
int m,a,b;
struct Node {
int x,y;
friend bool operator < (const Node &a, const Node &b)
{
return a.x>b.x; //x小的優先順序高。這是友元函式過載運算子<
//不能過載大於的,放棄吧,朋友吧。並且set是正常的順序,而優先佇列是相反的
};
Node(int _x,int _y){x=_x;y=_y;};
};
int main()
{
set<Node>s;
s.insert(Node(1,2));
s.insert(Node(2,1));
cout<<s.begin()->y<<endl;
// 下面是優先佇列,可以發現優先佇列和set是相反的。。
priority_queue<Node>q;
q.push(Node(1,2));
q.push(Node(2,1));
cout<<q.top().y<<endl;
//輸出 1
// 2
return 0;
}
2 把過載函式寫在外面
#include <iostream>
#include <bits/stdc++.h>
/* 1 pair也能過載吧。可以噠
2 優先佇列和set是相反的
3 一種策略是用仿函式(雖然他也很像過載),另一種是過載運算子。
*/
using namespace std;
int m,a,b;
struct Node {
int x,y;
Node(int _x,int _y){x=_x;y=_y;};
};
bool operator < (const Node &a, const Node &b)
{
return a.x>b.x; //x小的優先順序高。這是友元函式過載運算子<
//不能過載大於的,放棄吧,朋友吧。並且set是正常的順序,而優先佇列是相反的
};
int main()
{
set<Node>s;
s.insert(Node(1,2));
s.insert(Node(2,1));
cout<<s.begin()->y<<endl;
// 下面是優先佇列,可以發現優先佇列和set是相反的。。
priority_queue<Node>q;
q.push(Node(1,2));
q.push(Node(2,1));
cout<<q.top().y<<endl;
//輸出 1
// 2
return 0;
}
3 更好看的過載。
#include <iostream>
#include <bits/stdc++.h>
/* 1 pair也能過載吧。可以噠
2 優先佇列和set是相反的
3 一種策略是用仿函式(雖然他也很像過載),另一種是過載運算子。
*/
using namespace std;
int m,a,b;
struct Node {
int x,y;
bool operator < ( const struct Node &b )const//是不是很好看對吧、、
{
return this->x>b.x; //x小的優先順序高。這是友元函式過載運算子<
//不能過載大於的,放棄吧,朋友吧。並且set是正常的順序,而優先佇列是相反的
};
Node(int _x,int _y){x=_x;y=_y;};
};
int main()
{
set<Node>s;
s.insert(Node(1,2));
s.insert(Node(2,1));
cout<<s.begin()->y<<endl;
// 下面是優先佇列,可以發現優先佇列和set是相反的。。
priority_queue<Node>q;
q.push(Node(1,2));
q.push(Node(2,1));
cout<<q.top().y<<endl;
//輸出 1
// 2
return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int m,a,b;
struct Node {
int x,y;
Node(int _x,int _y){x=_x;y=_y;};
};
struct fir
{
/* const 這裡編譯沒有約束,但是對於明確的不可變參加上更嚴謹 */
bool operator() (const Node& a, const Node& b) const
{
return a.x > b.x;
}
};
struct sec
{
/* const 這裡編譯沒有約束,但是對於明確的不可變參加上更嚴謹 */
bool operator() (const Node& a, const Node& b) const
{
return a.x < b.x;
}
};
int main()
{
set<Node,fir>s;
s.insert(Node(1,2));
s.insert(Node(2,1));
cout<<s.begin()->y<<endl;
// 下面是優先佇列,可以發現優先佇列和set是相反的。。
priority_queue<Node,vector<Node>,sec>q;
q.push(Node(5,2));
q.push(Node(10,1));
cout<<q.top().x<<endl;
return 0;
}
如果沒啥事我還是希望用pair比較好。。因為上一次有一道題用node過載竟然t了。。用pair過了,有時間把這道題貼過來qwq
去重函式
#include <bits/stdc++.h>
using namespace std;
vector<int>a;
/* 1 unique之前用sort,unique並不把元素刪除,而是把他們移到後面,
返回的是 前面不重複元素的尾指標(stl左閉右開)。
2 erase刪除格式如下,前後迭代器,也是左閉右開。
*/
int main()
{
a.push_back(1);
a.push_back(1);
for(int i=2;i<5;i++)a.push_back(i);
cout<<endl;
sort(a.begin(),a.end());
unique(a.begin(),a.end());
for(int i=0;i<a.size();i++){
printf("%d ",a[i]);
}
cout<<endl;
cout<<(int)(unique(a.begin(),a.end())-a.begin())<<endl;;
a.erase(unique(a.begin(),a.end()),a.end());
for(int i=0;i<a.size();i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
2 set過載(set預設是返回最小的。並且用pair也不慢)
struct Node{
int to;
ll va;
/*Node(int _to,ll _va){
to=_to;
va=_va;
}*/
bool operator<(const Node &b)const{
return (this->va<b.va);
}
};
set<Node >se;