专门做图片的网站cms智联招聘网最新招聘官网
专门做图片的网站cms,智联招聘网最新招聘官网,手机端网站怎么做排名,鞍山网站建设工作室1. 栈的本质#xff1a;容器适配器
首先理解关键点#xff1a;C中的stack不是独立的容器#xff0c;而是“容器适配器”。它不自己管理内存#xff0c;而是包装一个已有的底层容器#xff08;默认是deque#xff09;#xff0c;为其添加栈的接口#xff08;LIFO操作这个构造函数有两种用法默认构造创建空栈使用已有容器构造复制容器内容作为栈的初始内容#include iostream #include stack #include vector #include deque int main() { // 1. 默认构造 - 空栈 std::stackint s1; // 使用默认的deque作为底层容器 std::cout s1 size: s1.size() std::endl; // 输出: 0 // 2. 使用vector作为底层容器指定容器类型 std::stackint, std::vectorint s2; std::cout s2 size: s2.size() std::endl; // 输出: 0 // 3. 使用已有容器初始化复制容器内容 std::vectorint vec {1, 2, 3, 4, 5}; std::stackint, std::vectorint s3(vec); // 使用vec初始化栈 std::cout s3 size: s3.size() std::endl; // 输出: 5 // 查看栈顶元素应该是vec的最后一个元素 std::cout s3 top: s3.top() std::endl; // 输出: 5 // 4. 使用deque初始化stack默认容器 std::dequeint deq {10, 20, 30}; std::stackint s4(deq); // 使用deque初始化栈 std::cout s4 top: s4.top() std::endl; // 输出: 30 // 5. 弹出元素验证栈的顺序LIFO std::cout \nPopping s3 elements: ; while (!s3.empty()) { std::cout s3.top() ; s3.pop(); } // 输出: 5 4 3 2 1 (后进先出) return 0; }1. explicit 关键字的作用// 错误示例不能隐式转换 std::vectorint vec {1, 2, 3}; // std::stackint s vec; // 错误不能隐式转换 // 正确示例必须显式调用构造函数 std::stackint, std::vectorint s(vec); // 正确2.底层容器类型默认使用 dequeT可以指定其他容器但必须支持back() - 访问最后一个元素push_back() - 末尾添加元素pop_back() - 删除末尾元素我们再看一个例子#include iostream #include stack #include list int main() { // 使用list作为底层容器初始化栈 std::liststd::string tasks {Task A, Task B, Task C}; std::stackstd::string, std::liststd::string taskStack(tasks); std::cout Processing tasks (LIFO):\n; while (!taskStack.empty()) { std::cout Processing: taskStack.top() std::endl; taskStack.pop(); } // 输出: // Processing: Task C // Processing: Task B // Processing: Task A return 0; }二.常用操作empty作用检查栈是否为空返回bool 类型栈为空时返回 true否则返回 false#include iostream #include stack int main() { std::stackint myStack; // 检查空栈 if (myStack.empty()) { std::cout 栈是空的 std::endl; // 会执行这里 } else { std::cout 栈不是空的 std::endl; } // 添加元素后检查 myStack.push(10); if (!myStack.empty()) { std::cout 现在栈不是空的 std::endl; // 会执行这里 } // 清空栈后检查 myStack.pop(); if (myStack.empty()) { std::cout 栈又变成空的了 std::endl; // 会执行这里 } return 0; }size作用返回栈中当前元素的个数返回无符号整型表示元素数量#include iostream #include stack int main() { std::stackstd::string nameStack; // 初始大小 std::cout 初始大小: nameStack.size() std::endl; // 输出: 0 // 添加元素 nameStack.push(Alice); nameStack.push(Bob); nameStack.push(Charlie); std::cout 添加3个元素后的大小: nameStack.size() std::endl; // 输出: 3 // 移除元素 nameStack.pop(); std::cout 移除1个元素后的大小: nameStack.size() std::endl; // 输出: 2 // 继续添加 nameStack.push(David); nameStack.push(Eve); std::cout 再添加2个元素后的大小: nameStack.size() std::endl; // 输出: 4 return 0; }top作用访问栈顶元素下一个要处理的元素但是不会移动栈顶元素它返回栈顶元素的引用可修改但不删除该元素。注意不会移除元素只是查看。如果栈为空调用此函数是未定义行为#include iostream #include stack int main() { std::stackint numbers; // 示例1: 基本使用 numbers.push(10); numbers.push(20); numbers.push(30); std::cout 栈顶元素: numbers.top() std::endl; // 输出: 30 // 示例2: 查看但不删除 std::cout 再次查看栈顶: numbers.top() std::endl; // 输出: 30 std::cout 栈大小仍然是: numbers.size() std::endl; // 输出: 3 // 示例3: 修改栈顶元素 numbers.top() 99; // 修改栈顶元素的值 std::cout 修改后栈顶元素: numbers.top() std::endl; // 输出: 99 return 0; }push作用插入元素到栈顶成为新的栈顶参数要插入的元素值会复制或移动#include iostream #include stack int main() { std::stackint numbers; // 基本使用 std::cout 初始栈大小: numbers.size() std::endl; numbers.push(10); std::cout push(10)后栈顶: numbers.top() std::endl; std::cout 栈大小: numbers.size() std::endl; numbers.push(20); std::cout push(20)后栈顶: numbers.top() std::endl; std::cout 栈大小: numbers.size() std::endl; numbers.push(30); std::cout push(30)后栈顶: numbers.top() std::endl; std::cout 栈大小: numbers.size() std::endl; return 0; }emplace作用在栈顶原地构造元素用法相比 push 更高效直接在栈顶位置构造对象避免临时对象的创建和拷贝参数构造元素所需的参数列表#include iostream #include stack #include string class Person { public: std::string name; int age; // 构造函数 Person(std::string n, int a) : name(n), age(a) { std::cout Person对象被构造: name std::endl; } // 拷贝构造函数 Person(const Person other) : name(other.name), age(other.age) { std::cout Person对象被拷贝: name std::endl; } // 移动构造函数 Person(Person other) noexcept : name(std::move(other.name)), age(other.age) { std::cout Person对象被移动: name std::endl; } }; int main() { std::stackPerson peopleStack; std::cout 使用 push() 创建临时对象 std::endl; // push会创建临时对象然后拷贝或移动到栈中 peopleStack.push(Person(Alice, 25)); // 输出: // Person对象被构造: Alice (临时对象) // Person对象被移动: Alice (移动到栈中) std::cout \n 使用 emplace() 直接构造 std::endl; // emplace直接在栈中构造对象避免临时对象 peopleStack.emplace(Bob, 30); // 输出: // Person对象被构造: Bob (直接在栈中构造) std::cout \n 访问栈顶 std::endl; std::cout 栈顶人员: peopleStack.top().name std::endl; // Bob // 更多emplace示例 std::stackstd::pairint, std::string pairStack; // 使用push需要创建pair对象 pairStack.push(std::pairint, std::string(1, Hello)); // 使用emplace更简洁高效 pairStack.emplace(2, World); // 直接在栈中构造pair std::cout \n栈顶pair: pairStack.top().first , pairStack.top().second std::endl; return 0; }pop作用移除栈顶元素弹出并丢弃当前栈顶元素注意不返回被移除的元素只移除。需要先使用 top() 获取值#include iostream #include stack int main() { std::stackint numbers; // 添加元素 for (int i 1; i 5; i) { numbers.push(i * 10); std::cout push( i * 10 ) std::endl; } std::cout \n当前栈大小: numbers.size() std::endl; std::cout 当前栈顶: numbers.top() std::endl; std::cout \n 开始pop操作 std::endl; // 安全地pop元素 if (!numbers.empty()) { std::cout 准备pop当前栈顶: numbers.top() std::endl; numbers.pop(); // 移除50 std::cout pop后栈顶变为: (numbers.empty() ? 空 : std::to_string(numbers.top())) std::endl; } std::cout \n 循环pop所有元素 std::endl; int count 0; while (!numbers.empty()) { count; std::cout 第 count 次pop前栈顶: numbers.top() std::endl; numbers.pop(); std::cout pop后栈大小: numbers.size() std::endl; } std::cout \n最终栈是否为空: (numbers.empty() ? 是 : 否) std::endl; return 0; }swap作用交换两个栈的内容用法高效交换两个栈的所有元素只交换内部指针不逐个拷贝元素参数要交换的另一个栈#include iostream #include stack #include string int main() { std::stackstd::string stack1; std::stackstd::string stack2; // 初始化stack1 stack1.push(Apple); stack1.push(Banana); stack1.push(Cherry); // 初始化stack2 stack2.push(Dog); stack2.push(Cat); std::cout 交换前: std::endl; std::cout stack1 大小: stack1.size() , 栈顶: (stack1.empty() ? 空 : stack1.top()) std::endl; std::cout stack2 大小: stack2.size() , 栈顶: (stack2.empty() ? 空 : stack2.top()) std::endl; // 交换两个栈的内容 stack1.swap(stack2); std::cout \n交换后: std::endl; std::cout stack1 大小: stack1.size() , 栈顶: (stack1.empty() ? 空 : stack1.top()) std::endl; std::cout stack2 大小: stack2.size() , 栈顶: (stack2.empty() ? 空 : stack2.top()) std::endl; return 0; }