[C++ STL] set使用詳解


一、概述

set 容器內的元素會被自動排序,set 與 map 不同,set 中的元素即是鍵值又是實值,set 不允許兩個元素有相同的鍵值。不能通過 set 的迭代器去修改 set 元素,原因是修改元素會破壞 set 組織。當對容器中的元素進行插入或者刪除時,操作之前的所有迭代器在操作之后依然有效。


二、定義及初始化

使用之前必須加相應容器的頭文件:

#include <set> // set屬於std命名域的,因此需要通過命名限定,例如using std::set;

定義的代碼如下:

set<int> a; // 定義一個int類型的集合a
// set<int> a(10); // error,未定義這種構造函數
// set<int> a(10, 1); // error,未定義這種構造函數
set<int> b(a); // 定義並用集合a初始化集合b
set<int> b(a.begin(), a.end()); // 將集合a中的所有元素作為集合b的初始值

除此之外,還可以直接使用數組來初始化向量:

int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5); // 將數組n的前5個元素作為集合a的初值

三、基本操作

3.1 容量函數

  • 容器大小:st.size();
  • 容器最大容量:st.max_size();
  • 容器判空:st.empty();
  • 查找鍵 key 的元素個數:st.count(key);
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i<6; i++)
	{
		st.insert(i);
	}

	cout << st.size() << endl; // 輸出:6
	cout << st.max_size() << endl; // 輸出:214748364
	cout << st.count(2) << endl; // 輸出:1
	if (st.empty())
		cout << "元素為空" << endl; // 未執行

	return 0;
}

3.2 添加函數

  • 在容器中插入元素:st.insert(const T& x);
  • 任意位置插入一個元素:st.insert(iterator it, const T& x);
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st;

	// 在容器中插入元素
	st.insert(4);
	// 任意位置插入一個元素
	set<int>::iterator it = st.begin();
	st.insert(it, 2);

	// 遍歷顯示
	for (it = st.begin(); it != st.end(); it++)
		cout << *it << " "; // 輸出:2 4
	cout << endl;

	return 0;
}

3.3 刪除函數

  • 刪除容器中值為 elem 的元素:st.pop_back(const T& elem);
  • 刪除it迭代器所指的元素:st.erase(iterator it);
  • 刪除區間 [first,last] 之間的所有元素:st.erase(iterator first, iterator last);
  • 清空所有元素:st.clear();
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i < 8; i++)
		st.insert(i);

	// 刪除容器中值為elem的元素
	st.erase(4);
	// 任意位置刪除一個元素
	set<int>::iterator it = st.begin();
	st.erase(it);
	// 刪除[first,last]之間的元素
	st.erase(st.begin(), ++st.begin());

	// 遍歷顯示
	for (it = st.begin(); it != st.end(); it++)
		cout << *it << " "; // 輸出:2 3 5 6 7
	cout << endl;

	// 清空所有元素
	st.clear();

    // 判斷set是否為空
    if (st.empty())
    	cout << "集合為空" << endl; // 輸出:集合為空

	return 0;
}

3.4 訪問函數

  • 查找鍵 key 是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回set.end(): st.find(key);
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i < 6; i++)
		st.insert(i);

	// 通過find(key)查找鍵值
	set<int>::iterator it;
	it = st.find(2);
	cout << *it << endl; // 輸出:2

	return 0;
}

3.5 其他函數

  • 交換兩個同類型容器的元素:swap(set&, set&);lst.swap(set&);
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st1;
	st1.insert(1);
	st1.insert(2);
	st1.insert(3);
	set<int> st2;
	st2.insert(4);
	st2.insert(5);
	st2.insert(6);
	// 交換兩個容器的元素
	st1.swap(st2);

	// 遍歷顯示
	cout << "交換后的st1: ";
	set<int>::iterator it;
	for (it = st1.begin(); it != st1.end(); it++)
		cout << *it << " "; // 輸出:4 5 6
	cout << endl;
	// 遍歷顯示
	cout << "交換后的st2: ";
	for (it = st2.begin(); it != st2.end(); it++)
		cout << *it << " "; // 輸出:1 2 3
	cout << endl;

	return 0;
}

四、迭代器與算法

1. 迭代器

  • 開始迭代器指針:st.begin();
  • 末尾迭代器指針:st.end(); // 指向最后一個元素的下一個位置
  • 指向常量的開始迭代器指針:st.cbegin(); // 意思就是不能通過這個指針來修改所指的內容,但還是可以通過其他方式修改的,而且指針也是可以移動的。
  • 指向常量的末尾迭代器指針:lst.cend();
  • 反向迭代器指針,指向最后一個元素:st.rbegin();
  • 反向迭代器指針,指向第一個元素的前一個元素:st.rend();
  • 返回最后一個 key<=keyElem 元素的迭代器:st.lower_bound(keyElem);
  • 返回第一個 key>keyElem 元素的迭代器: st.upper_bound(keyElem);
  • 返回容器中 key 與 keyElem 相等的上下限的兩個迭代器,這兩個迭代器被放在對組(pair)中: st.equal_range(keyElem);
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
	set<int> st;
	st.insert(1);
	st.insert(2);
	st.insert(3);

	cout << *(st.begin()) << endl; // 輸出:1
	cout << *(--st.end()) << endl; // 輸出:3
	cout << *(st.cbegin()) << endl; // 輸出:1
	cout << *(--st.cend()) << endl; // 輸出:3
	cout << *(st.rbegin()) << endl; // 輸出:3
	cout << *(--st.rend()) << endl; // 輸出:1
	cout << *(st.lower_bound(2)) << endl; // 輸出:2
	cout << *(st.upper_bound(2)) << endl; // 輸出:3
	pair<set<int>::iterator, set<int>::iterator> t_pair = st.equal_range(2);
	cout << *(t_pair.first) << endl; // 輸出:2
	cout << *(t_pair.second) << endl; // 輸出:3
	cout << endl;

	return 0;
}

2. 算法

  • 遍歷元素
set<int>::iterator it;
for (it = st.begin(); it != st.end(); it++)
    cout << *it << endl;

三、總結

可以看到,set 與序列式容器的用法有以下幾處不同:

  • set 不支持 resize() 函數;

  • set 容器不提供下標操作符。為了通過鍵從 set 中獲取元素,可使用 find 運算;

  • set 只能使用insert的兩種重載函數插入,不支持 push_back() 和 push_front() 函數;

  • set 不支持 STL 里的 reverse 和 sort 算法;

  • set 能不通過迭代器,只通過元素值來刪除該元素;

  • set 只支持默認構造函數和拷貝構造函數,沒有其它重載的構造函數。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM