c++ 集合操作


map

添加

map<int, int> my;
my.insert(make_pair(1, 5));  // 如果 key 存在,則添加失敗。返回 pair 如下折疊代碼塊
my[6] = 7;  // 如果 key 存在,則更新
my.insert({ 7,8 });
折疊代碼塊
 
map
   
   
   
           
             my; my.insert(make_pair(1, 5)); map 
            
              my; my.insert(make_pair(1, 5)); 
             
           

// insert 返回值為 pair.
pair<map<int, int>::iterator, bool> result = my.insert(make_pair(6, 2)); // 或者 make_pair(1,6)
if(!result.second)
{
cout << "error" << result.first->first << ' ' << result.first->second;
}
else
{
result.first++; // map 自動排序, 測試返回的是插入的位置
if (result.first == my.end())
cout << "success 且插在末位" ;
else
cout << "success 插入成功, 不是末尾";
}

遍歷

map<int, int> my;
my.insert(make_pair(1, 5));
	
for (map<int, int>::iterator item = my.begin(); item != my.end(); item++)
	cout << item->first << item->second << endl; // item 是個 pair, 不同於順序列表可以 *item.first

for (auto& item : my)
{
	cout << item.first << item.second;
}

只有順序容器vector可以 iterator+n, map等關聯容器只能 iterator++/iterator--

刪除與取值、修改

map<int, int> my;
my.insert(make_pair(1, 5));
my[1] = 99;
cout << my[1] << endl; // 99
my.erase(1);  // 單一刪除  
cout << my.size();
my.clear();  // 全部清空

find 查找

map<int, int> my;
my.insert(make_pair(1, 5));
	
if (my.find(1) != my.end())  // 找到,返回值位置. 找不到,返回位置為 end
	cout << my[1] << endl;
	
if (my.find(5) == my.end())
	cout << "無" << endl;

count 查找

1 if the container contains an element whose key is equivalent to k, or zero otherwise.

int result = my.count(1);
int result2 = my.count(2);
cout << result << result2;

返回查找到的 key 個數。因為 key 為唯一,所以只能為 0 or 1

Set

刪除

void erase (iterator position);
size_type erase (const value_type& val);  # 指定 value 
void erase (iterator first, iterator last);

可以選擇通過迭代器或者指定值進行刪除。(multiset 同樣是這三個函數)
第二種方式返回被刪除的個數。set 中因為鍵唯一,所以無非 0 1
multiset 因為可以存多個相同的值,所以返回值為 “被刪除相應的值的個數”

添加

返回值為 pair 類型, pair::first 是插入的返回位置,pair::second 為 bool 類型,代表是否 insert 成功。

set<int> my;
// 方式一
my.insert(4);
pair<set<int>::iterator, bool> result = my.insert(4);
if (!result.second)
	cout << "insert error" << endl;
	
// 方式二
vector<int> myv = { 9,9,10,4 };
my.insert(myv.begin(), myv.end());
for (auto& item : my)
{
	cout << item;
}

count find 查找, erase, 遍歷

同上文 map 一致, 不再贅述

vector

初始化

// 常用初始化方式
vector<int> my(7, 3); // 7 個三
vector<bool> my2(7, false);
vector<int> my3({ 1,2,8,9 }); // 直接賦值 1 2 8 9
vector<int> my4(my3.begin(), my3.end());

插入

vector<int> my;
my.push_back(5);  // 常用
my.emplace_back(6);// 意義同上, 效率更高

my.insert(my.begin() + 1, 8);  // 5 8 6 指定位置插入

刪除

vector<int> my{4,6,7,8};
my.pop_back(); // 刪除末尾
my.erase(my.begin() + 1);// 4 7 指定位置刪除

遍歷

vector<int> my3({ 1,2,8,9 }); // 直接賦值 1 2 8 9
// 方式1
for (vector<int>::iterator item = my3.begin(); item != my3.end(); item++) // 且可以 item+=2. map關聯迭代器不可
	cout << *item;  // 與map的迭代器不同
// 方式2
for (auto& item : my3)
{
	cout << item << ' ';
}

find

這個和關聯同期不一樣, 並不屬於 vector,是專門的函數

template<class InputIterator, class T>
  InputIterator find (InputIterator first, InputIterator last, const T& val)
{
  while (first!=last) {
    if (*first==val) return first;
    ++first;
  }
  return last;
}

傳入三個參數,1、2為迭代器位置(查找范圍),第3個參數為目標值.【返回迭代器位置,所以可以判斷是否找到了】

vector<int> my{4,6,7,8,9};
vector<int>::iterator result = find(my.begin(), my.end(), 10);
if (result != my.end())
{
	cout << "success 且 idx=" << result - my.begin();
}
else
	cout << "無";

find_if

其實看一下模板內容就發現和 find 很一致,只不過更靈活

template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

可以看到 pred(*first) 所以,也就是找第一個返回 pred 自定義函數的 iterator 位置 【頭文件 algorithm】

#include <algorithm>    // std::find_if
using namespace std;
bool IsOdd(int i) {
	return ((i % 2) == 1);
}
int main()
{
        vector<int> my{4,6,7,8,9};
        vector<int>::iterator result = find_if(my.begin(), my.end(), IsOdd);
	if (result != my.end())
	{
		cout << "success 且 idx=" << result - my.begin();
	}
	else
		cout << "無";

	return 0;

reverse

vector<int> my{4,6,7,9};
reverse(my.begin(), my.end());

string

構造方法

傳入【string】

// default
string();
// copy
string (const string& str);

傳入【字符串常量】

// substring
string (const char* s, size_t n);
// 323a
string str2("323aa", 4); // 截取前四位
// ca
string str3("32acab", 3, 2); // 第3位開始截取2位

// from c-string
string (const char* s);
// heeee
string str("heeee");

傳入【字符】

// fill
string (size_t n, char c);  【注意是數字在前, char 在后】
// aaaaaa
string str0(6, 'a'); // 賦值6份 

訪問、截取

string str2("323aa");
cout << str2[0] << endl; // 下標訪問
	
cout << str2.substr(2, 3);  // 從下標2開始截取3個

cout << str2.size() << str2.length();

插入 insert append

string str("323aa");

str.append("tyui");
str.insert(1, "插入");  // 3插入23aatyui
cout << str;

// str.insert(0, 5,'x'); 在[0] 插入 5 個 'x'

查找 find

看一下函數定義

// 返回無符號整數類型
string::size_t find (const string& str, size_t pos = 0) const;

這是 string 的內置函數,用於查找 str,pos 為起始查找位置【默認為0】,【返回結果】為查找到的第一個下標位置,沒找到返回 string::npos. 被定義成無符號數-1,但別使用-1來判斷,用string::npos

string s("jk1a2b3c4d5e6f7jkg8h9i1a2b3c4d5e6f7g8ha9i");
string::size_type position;

//find 函數 返回jk 在s 中的下標位置
position = s.find("jk");
	
//position = s.find("jk", 5); 
if (position != s.npos)  
      cout << position;
else
      cout << "No found";

例子:找指定字符串

string s("jk1a2b3c4d5e6f7jkg8h9i1a2b3c4d5e6f7g8ha9i*");
string str = "9i";

string::size_type position = 0;
while ((position = s.find(str, position)) != string::npos)  // 每次從 position 起始開始尋找
{
	cout << position << ' ';  // 輸出:20 39
	position += 1;
}

rfind 反向查找

和迭代器的 rbegin rend 一樣,從末尾開始查找,返回第一個查找到的下標。

string s("jk1a2b3c4d5e6f7jkg8h9i1a2b3c4d5e6f7g8ha9i*");
string str = "9i";

string::size_type position =  s.rfind(str);
cout << position;  // 輸出 39

同理,找不到的判斷

string::size_type position =  s.rfind(str);
if (position == string::npos)
{
	cout << "no found";
}

更多用法:https://www.cnblogs.com/wkfvawl/p/9429128.html

替換 replace

使用方式繁雜,我列一個最常用的: 替換 str pos 位置長度為 len,替換為 str_new。我們可以改造成替換string指定字符

string& replace (size_t pos, size_t len, const string& str); 
// 替換 is 為 |ohh|
string line = "this@ is@ a test string!";
string::size_type position = 0;
	
while ((position = line.find("is", position)) != string::npos)
{
	line.replace(position, 2, "|ohh|"); // pos len str_replace
	//position++;  //注意,因為不是查找,所以肯定每次都從 0 位置開始find
}
cout << line; // 輸出:th|ohh|@ |ohh|@ a test string!

find更多用法:
1.https://blog.csdn.net/jiary5201314/article/details/52502516
2.https://www.cnblogs.com/zpcdbky/p/4471454.html

去掉所有空格

// 刪除所有空格
string line = "  this@ is@ a test string!  ";
string::size_type position = 0;
string target = " ";
string replace_ = "";

while ((position = line.find(target, position)) != string::npos)
{
	line.replace(position, 1, replace_); // pos len str_replace
	//position++;  //注意,因為不是查找,所以肯定每次都從 0 位置開始find
}

cout << line;

刪除首尾空格

// 去掉首尾空格
string line = "  this@ is@ a test string!  ";
string::size_type position = 0;

line.erase(position, line.find_first_not_of(' '));
line.erase(line.find_last_not_of(' ') + 1, line.size()); // 注意+1,否則 !被刪除了
	
cout << line;

tuple

創建、取值、修改

tuple<int, int, string> my = make_tuple(3, 4, "sys");
tuple<int, int, string> my2(3, 4, "sys");
get<1>(my) = 99;
cout << get<1>(my) << get<2>(my); // 99 sys

pair

創建、取值、修改

// 創建
pair <std::string, double> product2("tomatoes", 2.30);   
pair <std::string, double> product3(product2);   
pair <std::string, double> product1 = make_pair(string("lightbulbs"), 0.99);

// 修改
product1.first = string("ohhhh");

// 取值
cout << product1.first << product1.second;


免責聲明!

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



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