C++模版类实现栈

news2024/9/28 8:09:27

text.h

#ifndef TEXT_H
#define TEXT_H


#include <stdexcept> // 用于 std::out_of_range

template <typename T>
class MyStack {
private:
    T* data;         // 指向底层数组的指针
    int capacity;    // 容量
    int top;         // 栈顶索引
    int size;        // 当前元素数量

    void resize(int new_capacity); // 扩容函数

public:
    // 无参构造函数
    MyStack();

    // 有参构造函数
    MyStack(int initial_capacity);

    // 拷贝构造函数
    MyStack(const MyStack& other);

    // 赋值运算符
    MyStack& operator=(const MyStack& other);

    // 析构函数
    ~MyStack();

    // 访问第一个元素
    T& front();

    // 访问最后一个元素
    T& back();

    // 检查栈是否为空
    bool is_empty() const;

    // 返回栈的元素数量
    int get_size() const;

    // 尾插
    void push(const T& value);

    // 尾删
    void pop();

    // 在尾部原位置构造元素
    template<typename... Args>
    void emplace_back(Args&&... args);

    // 删除首个元素
    void pop_front();

    // 交换内容
    void swap(MyStack& other);
  
};

#include "text.cpp" // 包含实现文件


#endif // TEXT_H

text.cpp

#include "text.h"



// 无参构造函数
template <typename T>
MyStack<T>::MyStack() : capacity(10), top(-1), size(0) {
    data = new T[capacity]; // 动态分配初始容量
}

// 有参构造函数
template <typename T>
MyStack<T>::MyStack(int initial_capacity) : capacity(initial_capacity), top(-1), size(0) {
    data = new T[capacity]; // 动态分配指定容量
}

// 拷贝构造函数
template <typename T>
MyStack<T>::MyStack(const MyStack& other) : capacity(other.capacity), top(other.top), size(other.size) {
    data = new T[capacity]; // 动态分配新数组
    for (int i = 0; i <= top; i++) {
        data[i] = other.data[i]; // 复制元素
    }
}

// 赋值运算符
template <typename T>
MyStack<T>& MyStack<T>::operator=(const MyStack& other) {
    if (this != &other) { // 防止自赋值
        delete[] data; // 释放原有内存
        capacity = other.capacity;
        top = other.top;
        size = other.size;
        data = new T[capacity]; // 动态分配新数组
        for (int i = 0; i <= top; i++) {
            data[i] = other.data[i]; // 复制元素
        }
    }
    return *this; // 返回当前对象
}

// 析构函数
template <typename T>
MyStack<T>::~MyStack() {
    delete[] data; // 释放动态分配的内存
}

// 访问第一个元素
template <typename T>
T& MyStack<T>::front() {
    if (is_empty()) {
        throw std::out_of_range("Stack is empty");
    }
    return data[0]; // 返回第一个元素
}

// 访问最后一个元素
template <typename T>
T& MyStack<T>::back() {
    if (is_empty()) {
        throw std::out_of_range("Stack is empty");
    }
    return data[top]; // 返回最后一个元素
}

// 检查栈是否为空
template <typename T>
bool MyStack<T>::is_empty() const {
    return size == 0; // 如果元素数量为0,返回true
}

// 返回栈的元素数量
template <typename T>
int MyStack<T>::get_size() const {
    return size; // 返回当前元素数量
}

// 尾插
template <typename T>
void MyStack<T>::push(const T& value) {
    if (size >= capacity) {
        resize(capacity * 2); // 扩容为原来的两倍
    }
    data[++top] = value; // 插入新元素
    size++; // 更新元素数量
}

// 尾删
template <typename T>
void MyStack<T>::pop() {
    if (is_empty()) {
        throw std::out_of_range("Stack is empty");
    }
    top--; // 移除栈顶元素
    size--; // 更新元素数量
}

// 在尾部原位置构造元素
template <typename T>
template<typename... Args>
void MyStack<T>::emplace_back(Args&&... args) {
    if (size >= capacity) {
        resize(capacity * 2); // 扩容为原来的两倍
    }
    data[++top] = T(std::forward<Args>(args)...); // 原位置构造元素
    size++; // 更新元素数量
}

// 删除首个元素
template <typename T>
void MyStack<T>::pop_front() {
    if (is_empty()) {
        throw std::out_of_range("Stack is empty");
    }
    for (int i = 0; i < top; i++) {
        data[i] = data[i + 1]; // 移动元素
    }
    top--; // 移除首个元素
    size--; // 更新元素数量
}

// 交换内容
template <typename T>
void MyStack<T>::swap(MyStack& other) {
    std::swap(data, other.data);
    std::swap(capacity, other.capacity);
    std::swap(top, other.top);
    std::swap(size, other.size);
}

// 扩容函数
template <typename T>
void MyStack<T>::resize(int new_capacity) {
    T* new_data = new T[new_capacity]; // 动态分配新数组
    for (int i = 0; i <= top; i++) {
        new_data[i] = data[i]; // 复制旧数据
    }
    delete[] data; // 释放旧内存
    data = new_data; // 更新指针
    capacity = new_capacity; // 更新容量
}


main.cpp

#include <iostream>
#include "text.h"

using namespace std;

int main() {
    MyStack<double> stack; // 创建一个整型栈

    // 尾插元素
    stack.push(99.99);
    stack.push(10.11);
    stack.push(88.88);
    stack.push(66.66);
    std::cout << "输出最后一个元素 " << stack.back() << std::endl;
    std::cout << "输出第一个元素 " << stack.front() << std::endl;
    std::cout << "输出长度 " << stack.get_size() << std::endl;

    // 删除首个元素
    stack.pop_front();
    std::cout << "输出删除后的第一个元素 " << stack.front() << std::endl;

    // 尾删元素
    stack.pop();
    std::cout << "删除后的最后一个元素 " << stack.back() << std::endl; 

    // 交换内容
    MyStack<double> stack2;
    stack2.push(4.99);
    stack2.push(1.11);
    stack.swap(stack2);
    std::cout << "输出交换后的stack的最后一个元素 " << stack.back() << std::endl; 
    std::cout << "输出交换后的stack2的最后一个元素 " << stack2.back() << std::endl; 

    return 0;
}

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

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

相关文章

了解Webpack并处理样式文件

目录 引入定义安装和使用配置文件命令配置单独文件指定文件 处理样式css-loader使用 style-loaderless-loaderPostCSSpostcss-loaderpostcss-preset-env 引入 随着前端的快速发展&#xff0c;目前前端的开发已经变的越来越复杂了&#xff1a; 比如开发过程中我们需要通过模块化…

物联网系统中高精度压力检测方案_压力变送器

01 物联网系统中为什么要使用压力变送器 在物联网系统中使用压力变送器的原因主要基于以下几个方面&#xff1a; 感知层的核心作用 物联网系统主要由感知层、传输层、平台层和应用层组成。感知层作为物联网的“排头兵”&#xff0c;负责收集物理世界中的各种信息。压力变送…

十大排序算法总结

完整文档见 排序算法总结——语雀文档 比较类排序&#xff1a;通过比较来决定元素间的相对次序&#xff0c;由于其时间复杂度不能突破O(nlogn)&#xff0c;因此也称为非线性时间比较类排序。 非比较类排序&#xff1a;不通过比较来决定元素间的相对次序&#xff0c;它可以突破…

李宏毅机器学习2022-HW9--Explainable AI

Task CNN explanation 11种食物图片分类&#xff0c;与HW3使用同一个dataset Bread, Diary product, Dessert, Egg, Fried food, Meat, Noodles/Pasta, Rice, Seafood, Soup, and Vegetables/Fruit 训练一个CNN model用于classification&#xff0c;并做一些explanations …

一站式家装服务管理系统

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本一站式家装服务管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数…

可商业化的数字孪生系统

可商业化的数字孪生系统 相关链接 演示地址 演示地址 更多获取 更多获取 源码地址 源码地址 数字孪生系统 数字孪生系统&#xff08;Digital Twin System&#xff09;是新一代科技赋能的核心技术&#xff0c;通过虚拟与现实的双向映射&#xff0c;实现对物理世界的全面感…

GAMES101(17~18节,物理材质模型)

材质 BRDF 材质&#xff1a;决定了光线与物体不同的作用方式 BRDF定义了物体材质,包含漫反射和镜面部分 BSDF &#xff08;scattering散射&#xff09; BRDF&#xff08;reflect反射&#xff09; BTDF 光线打击到物体上会向四面八方散射 反射 光线打击到物体上反射出去…

基于Java+SQL Server2008开发的(CS界面)个人财物管理系统

一、需求分析 个人财务管理系统是智能化简单化个人管理的重要的组成部分。并且随着计算机技术的飞速发展&#xff0c;计算机在管理方面应用的旁及&#xff0c;利用计算机来实现个人财务管理势在必行。本文首先介绍了个人财务管理系统的开发目的&#xff0c;其次对个人财务管理…

【C语言】指针篇 | 万字笔记

写在前面 在学习C语言过程&#xff0c;总有一个要点难点离不开&#xff0c;那就是大名鼎鼎的C语言指针&#xff0c;也是应为有指针的存在&#xff0c;使得C语言一直长盛不衰。因此不才把指针所学的所有功力都转换成这个笔记。希望对您有帮助&#x1f970;&#x1f970; 学习指…

【STM32开发环境搭建】-1-Keil(MDK) 5.27软件安装和注册教程

目录 1 安装前装备工作 2 安装KEIL(MDK-ARM) 5.27软件 3 注册KEIL(MDK-ARM) 5.27软件&#xff0c;获取License许可证 4 手动安装STM32F0&#xff0c;STM32F1&#xff0c;STM32F4&#xff0c;STM32F7&#xff0c;STM32H7的支持包 4.1 下载STM32的支持包 4.2 安装STM32的支…

JavaScript 中变量命名的最佳实践

全篇大概1500 字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间5分钟。 1. 避免使用 var 关键字&#xff1a;过时的产物 在现代 JavaScript 中&#xff0c;我们通常避免使用 var&#xff0c;而是选择 let 和 const&#xff0c;它们提供更可预测和块范围的行为&#x…

C++初阶:STL详解(七)——list的模拟实现

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 前言&#xff1a; 我们前面已经了解到了lis…

helm3 部署项目应用示例

一、用到的插件 1、存储卷-日志外挂&#xff1a; 存储类自己提前建 2、env变量-存储nacos信息 二、新建项目 # helm create test-gateway 三、修改values.yaml ## 删除内容 # Additional volumes on the output Deployment definition. volumes: [] # - name: foo # se…

助力智能作物植株统计分析,基于YOLOv7全系列【tiny/l/x】参数模型开发构建田间作物场景下智能精准小麦麦穗检测识别计数系统

农业实验研究的一些场景下&#xff0c;尝尝有对指定视野区域内作物植株数量进行便捷化智能自动化统计计数的需求&#xff0c;诸如&#xff1a;棉花植株统计、小麦植株统计、水稻植株统计等等&#xff0c;这些农业实验场景下&#xff0c;单纯依靠人工数数的方式来进行植株计数是…

SpringBoot--yml配置文件的时间/大小的单位转换

原文网址&#xff1a;SpringBoot--yml配置文件的时间/大小的单位转换_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍SpringBoot的yml&#xff08;properties&#xff09;配置文件的时间/大小的单位转换。 概述 SpringBoot可以将yml中的配置绑定到一个Java类的字段&#x…

论文笔记——Graph Bottlenecked Social Recommendation

文章地址 代码地址 1.1简介 随着社交网络的出现&#xff0c;社交推荐已经成为个性化服务的重要技术。最近&#xff0c;基于图的社交推荐通过捕捉高阶社交影响显示出了有希望的结果。大多数基于图的社交推荐的经验研究直接将观察到的社交网络纳入公式&#xff0c;并基于社交同…

【注册/登录安全分析报告:孔夫子旧书网】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

香港科技大学数据建模MSc(DDM)硕士学位项目25/26招生宣讲会-西安专场

香港科技大学数据建模MSc(DDM)硕士学位项目25/26招生宣讲会-西安专场 &#x1f559;时间&#xff1a;2024 年10 月12日&#xff08;周六&#xff09; 16:00 &#x1f3e0;地点&#xff1a; 西安交大南洋大酒店(交通大学青龙寺店) 行政会议室 &#x1f9d1;‍&#x1f393;嘉宾…

0基础学习PyTorch——GPU上训练和推理

大纲 创建设备训练推理总结 在《Windows Subsystem for Linux——支持cuda能力》一文中&#xff0c;我们让开发环境支持cuda能力。现在我们要基于《0基础学习PyTorch——时尚分类&#xff08;Fashion MNIST&#xff09;训练和推理》&#xff0c;将代码修改成支持cuda的训练和推…

[sql-03] 求阅读至少两章的人数

准备数据 CREATE TABLE book_read (bookid varchar(150) NOT NULL COMMENT 书籍ID,username varchar(150) DEFAULT NULL COMMENT 用户名,seq varchar(150) comment 章节ID ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT 用户阅读表insert into book_read values(《太子日子》…