20、map和set、unordered_map、un_ordered_set的复现

一、map

1、了解

map的使用和常考面试题等等,看这篇文章

  • map的key是有序的 ,值不可重复
  • 插入使用 insert的效率更高,而在"更新map的键值对时,使用 [ ]运算符效率更高 。"

注意

  • map 的lower和upper那2个函数,经常用在算法里。
  • 直接修改某一个键的值,用 运算符[ ]

2、map的复现

  • 可以使用红黑树代码 (可以放在.h文件里,然后.h放入cpp文件中,分文件编程)。
  • 直接调用红黑树 。
  • 剩下的部分与之前写stack、queue等等的是一样的。
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
using namespace std;
enum class Color{BLACK,RED};
template<class Key,class Value>
class RedBlackTree{class RBNode{public:RBNode* left;RBNode* right;RBNode* parent;Key key;Value value;Color color;RBNode(const Key& key,const Value& value):left(nullptr),right(nullptr),parent(nullptr),color(Color::RED),key(key),value(value){}RBNode():left(nullptr),right(nullptr),parent(nullptr),color(Color::BLACK){}};RBNode* nil;RBNode* root;size_t size;
public:RedBlackTree():nil(new RBNode()),root(nil),size(0){}~RedBlackTree(){if(root!=nil)destroy(root);delete nil;}
private:void inorderPrint(RBNode* node){if(node!=nil){inorderPrint(node->left);cout<<node->key<<" "<<node->value<<" ";inorderPrint(node->right);}}void destroy(RBNode* node){if(node!=nil){destroy(node->left);destroy(node->right);delete node;size--;}}RBNode* searchRBNode(const Key& key){RBNode* cur = root;while(cur!=nil){if(cur->key>key){cur = cur->left;}else if(cur->key<key){cur = cur->right;}else{return cur;}}return nil;}void leftRotate(RBNode* x){RBNode* y = x->right;x->right = y->left;if(y->left!=nil){y->left->parent = x;}y->parent = x->parent;if(x->parent!=nil){if(x->parent->left==x){x->parent->left = y;}else{x->parent->right = y;}}else{root = y;}y->left =x;x->parent = y;}void rightRotate(RBNode* y){RBNode* x = y->left;y->left = x->right;if(x->right!=nil){x->right->parent = y;}x->parent = y->parent;if(y->parent!=nil){if(y->parent->right==y){y->parent->right = x;}else{y->parent->left = x;}}else{root = x;}x->right = y;y->parent = x;}RBNode* minimum(RBNode* node){while(node->left!=nil){node=node->left;}return node;}void transPlant(RBNode* u,RBNode* v){if(u->parent==nil){root = v;}else if(u->parent->left==u){u->parent->left=v;}else{u->parent->right=v;}if(v!=nil)v->parent = u->parent;}void insertFixup(RBNode* node){RBNode* parent = node->parent;RBNode* grandparent;RBNode* uncle;RBNode* tmp;while(parent!=nil&&parent->color==Color::RED){grandparent = parent->parent;if(parent->parent->left==parent){uncle = grandparent->right;}else{uncle = grandparent->left;}if(uncle->color==Color::RED){parent->color=Color::BLACK;uncle->color=Color::BLACK;grandparent->color=Color::RED;node = grandparent;parent = node->parent;grandparent=parent->parent;continue;}if(grandparent->left==parent){//Lif(parent->right==node){//RleftRotate(parent);tmp = parent;parent = node;node = parent;}rightRotate(grandparent);grandparent->color = Color::RED;parent->color = Color::BLACK;}else{//Rif(parent->left==node){//LrightRotate(parent);tmp = parent;parent = node;node = parent;}leftRotate(grandparent);grandparent->color = Color::RED;parent->color = Color::BLACK;}}root->color=Color::BLACK;}void insertRBNode(const Key& key,const Value& value){RBNode* node = new RBNode(key,value);node->left = nil;node->right = nil;node->parent = nil;if(node==nil){return ;}RBNode* cur = root;RBNode* pre = nullptr;while(cur!=nil){pre = cur;if(key>cur->key){cur = cur->right;}else if(cur->key>key){cur = cur->left;}else{delete node;return ;}}if(pre==nullptr){root = node;}else{node->parent = pre;if(pre->key>key){pre->left = node;}else{pre->right = node;}}size++;insertFixup(node);}void deleteFixup(RBNode* x){RBNode* w;while((x!=root)&&(x!=nil)&&(x->color==Color::BLACK)){if(x->parent->left == x){w = x->parent->right;if(w->color==Color::RED){w->color=Color::BLACK;x->parent->color = Color::RED;leftRotate(x->parent);w = x->parent->right;}if(w->left->color==Color::BLACK&&w->right->color==Color::BLACK){w->color = Color::RED;x = x->parent;}else{if(w->right->color==Color::BLACK){//RLw->left->color = Color::BLACK;w->color = Color::RED;w->parent->color =Color::BLACK;rightRotate(w);w = x->parent->right;}w->right->color = w->color;w->color= x->parent->color;x->parent->color = Color::BLACK;leftRotate(x->parent);x = root;}}else{w = x->parent->left;if(w->color==Color::RED){w->color=Color::BLACK;x->parent->color = Color::RED;rightRotate(x->parent);w = x->parent->left;}if(w->left->color==Color::BLACK&&w->right->color==Color::BLACK){w->color = Color::RED;x = x->parent;}else{if(w->left->color==Color::BLACK){//LRw->right->color = Color::BLACK;w->color = Color::RED;x->parent->color = Color::BLACK;leftRotate(w);w = x->parent->left;}w->left->color = w->color;w->color = x->parent->color;w->parent->color = Color::BLACK;rightRotate(x->parent);x = root;}}}if(x!=nil)x->color = Color::BLACK;}void deleteRBNode(RBNode* z){RBNode* x;//替换RBNode* y= z;//删除Color y_origin_color = y->color;if(y->left==nil){x = y->right;transPlant(y, y->right);}else if(y->right==nil){x = y->left;transPlant(y, y->left);}else{y = minimum(z->right);y_origin_color = y->color;x = y->right;if(y->parent!=z){transPlant(y, x);y->right =z->right;z->right->parent = y;}transPlant(z, y);y->left = z->left;z->left->parent = y;y->color = z->color;}if(y_origin_color==Color::BLACK){deleteFixup(x);}delete z;size--;}
public:void print(){if(root!=nil)inorderPrint(root);cout<<endl;}size_t getSize(){return size;}void clear(){if(root!=nil)destroy(root);}void remove(const Key& key){RBNode* node = searchRBNode(key);if(node==nil){return;}deleteRBNode(node);}bool empty() const {return size == 0;}void insert(const Key& key,const Value& value){insertRBNode(key,value);}Value* at(const Key& key){RBNode* node = searchRBNode(key);if(node!=nil){return &node->value;}else{return nullptr;}}
};template <typename Key, typename Value> class Map {
public:Map() : rbTree() {}void insert(const Key &key, const Value &value) { rbTree.insert(key, value); }void erase(const Key &key) { rbTree.remove(key); }size_t size() { return rbTree.getSize(); }bool empty() { return rbTree.empty(); }bool contains(const Key &key) { return rbTree.at(key) != nullptr; }Value &at(const Key &key) {Value *foundVal = rbTree.at(key);if (foundVal) {return *foundVal;} else {throw std::out_of_range("Key not found");}}Value &operator[](const Key &key) {Value *foundVal = rbTree.at(key);if (foundVal) {// 如果键存在,返回关联的值return *foundVal; // 或者,返回与找到的键关联的值} else {// 如果键不存在,插入新键值对,并返回新插入的值的引用Value defaultValue;rbTree.insert(key, defaultValue);return *rbTree.at(key);}}private:RedBlackTree<Key, Value> rbTree;
};
// main函数
int main() {Map<int, int> map;int N;std::cin >> N;getchar();std::string line;for (int i = 0; i < N; i++) {std::getline(std::cin, line);std::istringstream iss(line);std::string command;iss >> command;int key;int value;if (command == "insert") {iss >> key >> value;map.insert(key, value);}if (command == "erase") {iss >> key;map.erase(key);}if (command == "contains") {iss >> key;if (map.contains(key)) {std::cout << "true" << std::endl;} else {std::cout << "false" << std::endl;}}if (command == "at") {iss >> key;try {std::cout << map.at(key) << std::endl;} catch (const std::out_of_range& e) {std::cout << "not exist" << std::endl;}}// size 命令if (command == "size") {std::cout << map.size() << std::endl;}// empty 命令if (command == "empty") {if (map.empty()) {std::cout << "true" << std::endl;} else {std::cout << "false" << std::endl;}}}return 0;
}

二、set

1、了解

看这篇文章就够了

2、代码


#include <cstddef>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
using namespace std;
enum class Color{BLACK,RED};
template<class Key,class Value>
class RBTree{class RBNode{public:RBNode* left;RBNode* right;RBNode* parent;Key key;Value value;Color color;RBNode(const Key& key,const Value& value):left(nullptr),right(nullptr),parent(nullptr),color(Color::RED),key(key),value(value){}RBNode():left(nullptr),right(nullptr),parent(nullptr),color(Color::BLACK){}};RBNode* nil;RBNode* root;size_t size;
public:RBTree():nil(new RBNode()),root(nil),size(0){}~RBTree(){if(root!=nil)destroy(root);delete nil;}
private:void inorderPrint(RBNode* node){if(node!=nil){inorderPrint(node->left);cout<<node->key<<" "<<node->value<<" ";inorderPrint(node->right);}}void destroy(RBNode* node){if(node!=nil){destroy(node->left);destroy(node->right);delete node;}size = 0;}RBNode* searchRBNode(const Key& key){RBNode* cur = root;while(cur!=nil){if(cur->key>key){cur = cur->left;}else if(cur->key<key){cur = cur->right;}else{return cur;}}return nil;}void leftRotate(RBNode* x){RBNode* y = x->right;x->right = y->left;if(y->left!=nil){y->left->parent = x;}y->parent = x->parent;if(x->parent!=nil){if(x->parent->left==x){x->parent->left = y;}else{x->parent->right = y;}}else{root = y;}y->left =x;x->parent = y;}void rightRotate(RBNode* y){RBNode* x = y->left;y->left = x->right;if(x->right!=nil){x->right->parent = y;}x->parent = y->parent;if(y->parent!=nil){if(y->parent->right==y){y->parent->right = x;}else{y->parent->left = x;}}else{root = x;}x->right = y;y->parent = x;}RBNode* minimum(RBNode* node){while(node->left!=nil){node=node->left;}return node;}void transPlant(RBNode* u,RBNode* v){if(u->parent==nil){root = v;}else if(u->parent->left==u){u->parent->left=v;}else{u->parent->right=v;}v->parent = u->parent;}void insertFixup(RBNode* node){RBNode* parent = node->parent;RBNode* grandparent;RBNode* uncle;RBNode* tmp;while(parent!=nil&&parent->color==Color::RED){grandparent = parent->parent;if(parent->parent->left==parent){uncle = grandparent->right;}else{uncle = grandparent->left;}if(uncle->color==Color::RED){parent->color=Color::BLACK;uncle->color=Color::BLACK;grandparent->color=Color::RED;node = grandparent;parent = node->parent;grandparent=parent->parent;continue;}if(grandparent->left==parent){//Lif(parent->right==node){//RleftRotate(parent);tmp = parent;parent = node;node = parent;}rightRotate(grandparent);grandparent->color = Color::RED;parent->color = Color::BLACK;}else{//Rif(parent->left==node){//LrightRotate(parent);tmp = parent;parent = node;node = parent;}leftRotate(grandparent);grandparent->color = Color::RED;parent->color = Color::BLACK;}}root->color=Color::BLACK;}void insertRBNode(const Key& key,const Value& value){RBNode* node = new RBNode(key,value);node->left = nil;node->right = nil;node->parent = nil;if(node==nil){return ;}RBNode* cur = root;RBNode* pre = nullptr;while(cur!=nil){pre = cur;if(key>cur->key){cur = cur->right;}else if(cur->key>key){cur = cur->left;}else{delete node;return ;}}if(pre==nullptr){root = node;}else{node->parent = pre;if(pre->key>key){pre->left = node;}else{pre->right = node;}}size++;insertFixup(node);}void deleteFixup(RBNode* x){RBNode* w;while((x!=root)&&(x->color==Color::BLACK)){if(x->parent->left == x){w = x->parent->right;if(w->color==Color::RED){w->color=Color::BLACK;x->parent->color = Color::RED;leftRotate(x->parent);w = x->parent->right;}if(w->left->color==Color::BLACK&&w->right->color==Color::BLACK){w->color = Color::RED;x = x->parent;}else{if(w->right->color==Color::BLACK){//RLw->left->color = Color::BLACK;w->color = Color::RED;w->parent->color =Color::BLACK;rightRotate(w);w = x->parent->right;}w->right->color = w->color;w->color= w->parent->color;w->parent->color = Color::BLACK;leftRotate(x->parent);x = root;}}else{w = x->parent->left;if(w->color==Color::RED){w->color=Color::BLACK;x->parent->color = Color::RED;rightRotate(x->parent);w = x->parent->left;}if(w->left->color==Color::BLACK&&w->right->color==Color::BLACK){w->color = Color::RED;x = x->parent;}else{if(w->left->color==Color::BLACK){//LRw->right->color = Color::BLACK;w->color = Color::RED;x->parent->color = Color::BLACK;rightRotate(w);w = x->parent->left;}w->left->color = w->color;w->color= w->parent->color;w->parent->color = Color::BLACK;leftRotate(x->parent);x = root;}}}x->color = Color::BLACK;}void deleteRBNode(RBNode* z){RBNode* x;//替换RBNode* y= z;//删除Color y_origin_color = y->color;if(y->left==nil){x = y->right;transPlant(y, x);}else if(y->right==nil){x = y->left;transPlant(y, x);}else{y = z->right;y = minimum(y);y_origin_color = y->color;x = y->right;if(y->parent!=z){transPlant(y, x);y->right =z->right;z->right->parent = y;}transPlant(z, y);y->left = z->left;z->left->parent = y;y->color = z->color;}if(y_origin_color==Color::BLACK){deleteFixup(x);}delete z;size--;}
public:void print(){if(root!=nil)inorderPrint(root);cout<<endl;}size_t getSize(){return size;}void clear(){if(root!=nil)destroy(root);}void remove(const Key& key){RBNode* node = searchRBNode(key);if(node==nil){return;}deleteRBNode(node);}bool empty() const {return size == 0;}void insert(const Key& key,const Value& value){insertRBNode(key,value);}Value* at(const Key& key){RBNode* node = searchRBNode(key);if(node!=nil){return &node->value;}else{return nullptr;}}
};template <typename Key>
class Set {
public:Set() : rbTree() {}void insert(const Key &key) { rbTree.insert(key, key); }void erase(const Key &key) { rbTree.remove(key); }size_t size() { return rbTree.getSize(); }bool empty() { return rbTree.empty(); }bool contains(const Key &key) { return rbTree.at(key) != nullptr; }private:RBTree<Key, Key> rbTree;
};int main() {Set<int> mySet;int N;std::cin >> N;getchar();std::string line;for (int i = 0; i < N; i++) {std::getline(std::cin, line);std::istringstream iss(line);std::string command;iss >> command;int element;if (command == "insert") {iss >> element;mySet.insert(element);}if (command == "earse") {iss >> element;mySet.erase(element);}if (command == "contains") {iss >> element;std::cout << (mySet.contains(element) ? "true" : "false") << std::endl;}if (command == "size") {std::cout << mySet.size() << std::endl;}if (command == "empty") {std::cout << (mySet.empty() ? "true" : "false") << std::endl;}}return 0;
}

三、unordered_map的理解

#include <cstddef>
#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <list>
#include <utility>
#include <vector>
#include <sstream>
#include <string>template <typename Key, typename Value, typename Hash = std::hash<Key>>
class HashTable {class HashNode {public:Key key;Value value;// 从Key构造节点,Value使用默认构造explicit HashNode(const Key &key) : key(key), value() {}// 从Key和Value构造节点HashNode(const Key &key, const Value &value) : key(key), value(value) {}// 比较算符重载,只按照key进行比较bool operator==(const HashNode &other) const { return key == other.key; }bool operator!=(const HashNode &other) const { return key != other.key; }bool operator<(const HashNode &other) const { return key < other.key; }bool operator>(const HashNode &other) const { return key > other.key; }bool operator==(const Key &key_) const { return key == key_; }void print() const {std::cout << "key: " << key << " value: " << value << " ";}};private:using Bucket = std::list<HashNode>; // 定义桶的类型为存储键的链表std::vector<Bucket> buckets;        // 存储所有桶的动态数组Hash hashFunction;                  // 哈希函数对象size_t tableSize;                   // 哈希表的大小,即桶的数量size_t numElements;                 // 哈希表中元素的数量float maxLoadFactor = 0.75; // 默认的最大负载因子// 计算键的哈希值,并将其映射到桶的索引size_t hash(const Key &key) const { return hashFunction(key) % tableSize; }// 当元素数量超过最大负载因子定义的容量时,增加桶的数量并重新分配所有键void rehash(size_t newSize) {std::vector<Bucket> newBuckets(newSize); // 创建新的桶数组for (Bucket &bucket : buckets) {      // 遍历旧桶for (HashNode &hashNode : bucket) { // 遍历桶中的每个键size_t newIndex =hashFunction(hashNode.key) % newSize; // 为键计算新的索引newBuckets[newIndex].push_back(hashNode); // 将键添加到新桶中}}buckets = std::move(newBuckets); // 使用移动语义更新桶数组tableSize = newSize;             // 更新哈希表大小}public:// 构造函数初始化哈希表HashTable(size_t size = 10, const Hash &hashFunc = Hash()): buckets(size), hashFunction(hashFunc), tableSize(size), numElements(0) {}// 插入键到哈希表中void insert(const Key &key, const Value &value) {if ((numElements + 1) > maxLoadFactor * tableSize) { // 检查是否需要重哈希rehash(tableSize * 2); // 重哈希,桶数量翻倍}size_t index = hash(key);                     // 计算键的索引std::list<HashNode> &bucket = buckets[index]; // 获取对应的桶// 如果键不在桶中,则添加到桶中if (std::find(bucket.begin(), bucket.end(), key) == bucket.end()) {bucket.push_back(HashNode(key, value));++numElements; // 增加元素数量}}void insertKey(const Key &key) { insert(key, Value{}); }// 从哈希表中移除键void erase(const Key &key) {size_t index = hash(key);      // 计算键的索引auto &bucket = buckets[index]; // 获取对应的桶auto it = std::find(bucket.begin(), bucket.end(), key); // 查找键if (it != bucket.end()) {                               // 如果找到键bucket.erase(it); // 从桶中移除键numElements--;    // 减少元素数量}}// 查找键是否存在于哈希表中Value *find(const Key &key) {size_t index = hash(key);      // 计算键的索引auto &bucket = buckets[index]; // 获取对应的桶// 返回键是否在桶中auto ans = std::find(bucket.begin(), bucket.end(), key);if (ans != bucket.end()) {return &ans->value;};return nullptr;}// 获取哈希表中元素的数量size_t size() const { return numElements; }// 打印哈希表中的所有元素void print() const {std::cout << "HashTable elements:" << std::endl;for (size_t i = 0; i < buckets.size(); ++i) {std::cout << "Bucket " << i << ": ";for (const HashNode &element : buckets[i]) {element.print();}std::cout << std::endl;}}void clear() {this->buckets.clear();this->numElements = 0;}
};template <typename Key, typename Value> class Unordered_map {
private:HashTable<Key, Value> hashtable;public:Unordered_map() : hashtable(){};~Unordered_map() {}bool empty() const noexcept { return hashtable.size() == 0; }size_t size() const noexcept { return hashtable.size(); }void clear() noexcept { hashtable.clear(); }void insert(const Key &key, const Value &value) {hashtable.insert(key, value);}void erase(const Key &key) { hashtable.erase(key); }bool find(const Key &key) { return hashtable.find(key) != nullptr; }Value &operator[](const Key &key) {Value *ans = hashtable.find(key);if (ans != nullptr) {return *ans;}hashtable.insertKey(key);ans = hashtable.find(key);return *ans;}
};int main() {Unordered_map<int, int> map;int N;std::cin >> N;getchar();std::string line;for (int i = 0; i < N; i++) {std::getline(std::cin, line);std::istringstream iss(line);std::string command;iss >> command;int key;int value;if (command == "insert") {iss >> key >> value;map.insert(key, value);}if (command == "erase") {iss >> key;map.erase(key);}if (command == "find") {iss >> key;if (map.find(key)) {std::cout << "true" << std::endl;} else {std::cout << "false" << std::endl;}}// size 命令if (command == "size") {std::cout << map.size() << std::endl;}// empty 命令if (command == "empty") {if (map.empty()) {std::cout << "true" << std::endl;} else {std::cout << "false" << std::endl;}}}return 0;
}

四、unordered_set的理解

#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <list>
#include <utility>
#include <vector>
#include <sstream>
#include <string>template <typename Key, typename Value, typename Hash = std::hash<Key>>
class HashTable {class HashNode {public:Key key;Value value;// 从Key构造节点,Value使用默认构造explicit HashNode(const Key &key) : key(key), value() {}// 从Key和Value构造节点HashNode(const Key &key, const Value &value) : key(key), value(value) {}// 比较算符重载,只按照key进行比较bool operator==(const HashNode &other) const { return key == other.key; }bool operator!=(const HashNode &other) const { return key != other.key; }bool operator<(const HashNode &other) const { return key < other.key; }bool operator>(const HashNode &other) const { return key > other.key; }bool operator==(const Key &key_) const { return key == key_; }void print() const {std::cout << key << " "<< value << " ";}};private:using Bucket = std::list<HashNode>; // 定义桶的类型为存储键的链表std::vector<Bucket> buckets;        // 存储所有桶的动态数组Hash hashFunction;                  // 哈希函数对象size_t tableSize;                   // 哈希表的大小,即桶的数量size_t numElements;                 // 哈希表中元素的数量float maxLoadFactor = 0.75; // 默认的最大负载因子// 计算键的哈希值,并将其映射到桶的索引size_t hash(const Key &key) const { return hashFunction(key) % tableSize; }// 当元素数量超过最大负载因子定义的容量时,增加桶的数量并重新分配所有键void rehash(size_t newSize) {std::vector<Bucket> newBuckets(newSize); // 创建新的桶数组for (Bucket &bucket : buckets) {      // 遍历旧桶for (HashNode &hashNode : bucket) { // 遍历桶中的每个键size_t newIndex =hashFunction(hashNode.key) % newSize; // 为键计算新的索引newBuckets[newIndex].push_back(hashNode); // 将键添加到新桶中}}buckets = std::move(newBuckets); // 使用移动语义更新桶数组tableSize = newSize;             // 更新哈希表大小}public:// 构造函数初始化哈希表HashTable(size_t size = 10, const Hash &hashFunc = Hash()): buckets(size), hashFunction(hashFunc), tableSize(size), numElements(0) {}// 插入键到哈希表中void insert(const Key &key, const Value &value) {if ((numElements + 1) > maxLoadFactor * tableSize) { // 检查是否需要重哈希if (tableSize == 0) tableSize = 1;rehash(tableSize * 2); // 重哈希,桶数量翻倍}size_t index = hash(key);                     // 计算键的索引std::list<HashNode> &bucket = buckets[index]; // 获取对应的桶// 如果键不在桶中,则添加到桶中if (std::find(bucket.begin(), bucket.end(), key) == bucket.end()) {bucket.push_back(HashNode(key, value));++numElements; // 增加元素数量}}void insertKey(const Key &key) { insert(key, Value{}); }// 从哈希表中移除键void erase(const Key &key) {size_t index = hash(key);      // 计算键的索引auto &bucket = buckets[index]; // 获取对应的桶auto it = std::find(bucket.begin(), bucket.end(), key); // 查找键if (it != bucket.end()) {                               // 如果找到键bucket.erase(it); // 从桶中移除键numElements--;    // 减少元素数量}}// 查找键是否存在于哈希表中Value *find(const Key &key) {size_t index = hash(key);      // 计算键的索引auto &bucket = buckets[index]; // 获取对应的桶// 返回键是否在桶中auto ans = std::find(bucket.begin(), bucket.end(), key);if (ans != bucket.end()) {return &ans->value;};return nullptr;}// 获取哈希表中元素的数量size_t size() const { return numElements; }// 打印哈希表中的所有元素void print() const {for (size_t i = 0; i < buckets.size(); ++i) {for (const HashNode &element : buckets[i]) {element.print();}std::cout << std::endl;}}void clear() {this->buckets.clear();this->numElements = 0;this->tableSize = 0;}
};template <typename Key> class Unordered_set {
public:Unordered_set() : hashtable(){};~Unordered_set() {}bool empty() const noexcept { return hashtable.size() == 0; }size_t size() const noexcept { return hashtable.size(); }void clear() noexcept { hashtable.clear(); }void insert(Key key) { hashtable.insertKey(key); }void erase(Key key) { hashtable.erase(key); }bool find(const Key &key) { return hashtable.find(key) != nullptr; }private:HashTable<Key, Key> hashtable;
};int main() {Unordered_set<int> mySet;int N;std::cin >> N;getchar();std::string line;for (int i = 0; i < N; i++) {std::getline(std::cin, line);std::istringstream iss(line);std::string command;iss >> command;int element;if (command == "insert") {iss >> element;mySet.insert(element);}if (command == "erase") {iss >> element;mySet.erase(element);}if (command == "find") {iss >> element;std::cout << (mySet.find(element) ? "true" : "false") << std::endl;}if (command == "size") {std::cout << mySet.size() << std::endl;}if (command == "empty") {std::cout << (mySet.empty() ? "true" : "false") << std::endl;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80715.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Amazon Bedrock 和 Amazon Connect 打造智能客服自助服务 – 设计篇

随着 GenAI 技术不断的发展和演进&#xff0c;人工智能技术广泛地被应用在呼叫中心服务领域&#xff0c;主要包括虚拟坐席&#xff08;即自助服务&#xff09;、坐席助手和呼叫中心运营的数据洞察和智能分析。本博客主要针对自助服务应用场景的实现。 1. 传统自助服务系统瓶颈 …

java高效实现爬虫

一、前言 在Web爬虫技术中&#xff0c;Selenium作为一款强大的浏览器自动化工具&#xff0c;能够模拟真实用户操作&#xff0c;有效应对JavaScript渲染、Ajax加载等复杂场景。而集成代理服务则能够解决IP限制、地域访问限制等问题。本文将详细介绍如何利用JavaSelenium快代理实…

【计算机视觉】OpenCV实战项目:基于OpenCV的车牌识别系统深度解析

基于OpenCV的车牌识别系统深度解析 1. 项目概述2. 技术原理与算法设计2.1 图像预处理1) 自适应光照补偿2) 边缘增强 2.2 车牌定位1) 颜色空间筛选2) 形态学操作3) 轮廓分析 2.3 字符分割1) 投影分析2) 连通域筛选 2.4 字符识别 3. 实战部署指南3.1 环境配置3.2 项目代码解析 4.…

Python核心数据类型全解析:字符串、列表、元组、字典与集合

导读&#xff1a; Python 是一门功能强大且灵活的编程语言&#xff0c;而其核心数据类型是构建高效程序的基础。本文深入剖析了 Python 的五大核心数据类型——字符串、列表、元组、字典和集合&#xff0c;结合实际应用场景与最佳实践&#xff0c;帮助读者全面掌握这些数据类型…

GPT-4.1和GPT-4.1-mini系列模型支持微调功能,助力企业级智能应用深度契合业务需求

微软继不久前发布GPT-4.1系列模型后&#xff0c;Azure OpenAI服务&#xff08;国际版&#xff09;现已正式开放对GPT-4.1和GPT-4.1-mini的微调功能&#xff0c;并通过Azure AI Foundry&#xff08;国际版&#xff09;提供完整的部署和管理解决方案。这一重大升级标志着企业级AI…

构造+简单树状

昨日的牛客周赛算是比较简单的&#xff0c;其中最后一道构造题目属实眼前一亮。 倒数第二个题目也是一个很好的模拟题目&#xff08;考验对二叉树的理解和代码的细节&#xff09; 给定每一层的节点个数&#xff0c;自己拟定一个父亲节点&#xff0c;构造一个满足条件的二叉树。…

apache2的默认html修改

使用127.0.0.1的时候&#xff0c;默认打开的是index.html&#xff0c;可以通过配置文件修改成我们想要的html vi /etc/apache2/mods-enabled/dir.conf <IfModule mod_dir.c>DirectoryIndex WS.html index.html index.cgi index.pl index.php index.xhtml index.htm <…

mysql性能提升方法大汇总

前言 最近在开发自己的小程序的时候&#xff0c;由于业务功能对系统性能的要求很高&#xff0c;系统性能损耗又主要在mysql上&#xff0c;而业务功能的数据表很多&#xff0c;单表数据量也很大&#xff0c;又涉及到很多场景的数据查询&#xff0c;所以我针对mysql调用做了优化…

多模态RAG与LlamaIndex——1.deepresearch调研

摘要 关键点&#xff1a; 多模态RAG技术通过结合文本、图像、表格和视频等多种数据类型&#xff0c;扩展了传统RAG&#xff08;检索增强生成&#xff09;的功能。LlamaIndex是一个开源框架&#xff0c;支持多模态RAG&#xff0c;提供处理文本和图像的模型、嵌入和索引功能。研…

LabVIEW中算法开发的系统化解决方案与优化

在 LabVIEW 开发环境中&#xff0c;算法实现是连接硬件数据采集与上层应用的核心环节。由于图形化编程范式与传统文本语言存在差异&#xff0c;LabVIEW 中的算法开发需要特别关注执行效率、代码可维护性以及与硬件资源的适配性。本文从算法架构设计、性能优化到工程实现&#x…

OpenCV中的光流估计方法详解

文章目录 一、引言二、核心算法原理1. 光流法基本概念2. 算法实现步骤 三、代码实现详解1. 初始化设置2. 特征点检测3. 光流计算与轨迹绘制 四、实际应用效果五、优化方向六、结语 一、引言 在计算机视觉领域&#xff0c;运动目标跟踪是一个重要的研究方向&#xff0c;广泛应用…

零基础入门MySQL:10分钟搞定数据库基本操作

&#x1f4da; 一、MySQL是什么&#xff1f; MySQL 是一个关系型数据库管理系统&#xff08;简单理解&#xff1a;用“表格”存储数据的仓库&#xff09;。 就像Excel表格一样&#xff0c;数据按行和列整齐存放&#xff0c;方便快速查找和管理&#xff01; 为什么要学MySQL&a…

LeetCode 3335.字符串转换后的长度 I:I先递推

【LetMeFly】3335.字符串转换后的长度 I&#xff1a;I先递推 力扣题目链接&#xff1a;https://leetcode.cn/problems/total-characters-in-string-after-transformations-i/ 给你一个字符串 s 和一个整数 t&#xff0c;表示要执行的 转换 次数。每次 转换 需要根据以下规则替…

Linux 系统如何挂载U盘

一、问题描述 Linux系统不像Windows系统有图形化界面&#xff0c;对于机房服务器安装的Linux尤其如此&#xff0c;那么有时候需要拷贝U盘或者光盘的文件到Linux系统中去&#xff0c;与 Windows 系统自动为 U 盘分配盘符不同&#xff0c;Linux 系统需要手动将 U 盘挂载到指定目…

Qt进阶开发:QTcpServer的详解

文章目录 一、QTcpServer 简介二、常用成员函数的使用三、信号函数的使用四、虚函数的使用五、连接多客户端-服务端示例一、QTcpServer 简介 QTcpServer 是 Qt 网络模块中的一个核心类,用于实现 基于 TCP 协议的服务端(Server),它负责监听端口、接收客户端连接请求,并通过…

大项目k8s集群有多大规模,多少节点,有多少pod

1. 实际参与过生产级 K8s 集群 回答示例&#xff1a; 目前我负责的 K8s 集群规模为 300 个物理节点&#xff0c;分布在 3 个可用区&#xff08;AZ&#xff09;&#xff0c;采用多控制平面高可用架构。集群日常运行约 12,000 个 Pod&#xff0c;资源利用率保持在 65%-75%&#…

是 OpenCV 的 CUDA 模块中用于在 GPU 上对图像或矩阵进行转置操作函数cv::cuda::transpose

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::transpose 是 OpenCV 的 CUDA 模块中的一个函数&#xff0c;用于在 GPU 上对图像或矩阵进行转置操作&#xff08;Transpose&#xff0…

使用 goaccess 分析 nginx 访问日志

介绍 goaccess 是一个在本地解析日志的工具, 可以直接在命令行终端环境中使用 TUI 界面查看分析结果, 也可以导出为更加丰富的 HTML 页面. 官网: https://goaccess.io/ 下载安装 常见的 Linux 包管理器中都包含了 goaccess, 直接安装就行. 以 Ubuntu 为例: sudo apt instal…

Google LLM prompt engineering(谷歌提示词工程指南)

文章目录 基本概念AI输出配置&#xff1a;调整AI的回答方式输出长度温度&#xff08;Temperature&#xff09;Top-K和Top-P 提示技术&#xff1a;让AI更好地理解你零样本提示&#xff08;Zero-shot&#xff09;少样本提示&#xff08;Few-shot&#xff09;系统提示&#xff08;…

简单介绍Qt的属性子系统

深入理解Qt的属性系统 ​ 笔者最近正在大规模的开发Qt的项目和工程&#xff0c;这里笔者需要指出的是&#xff0c;这个玩意在最常规的Qt开发中是相对比较少用的&#xff0c;笔者也只是在Qt的QPropertyAnimation需要动画感知笔者设置的一个属性的时候方才知道这个东西的。因此&…