C++学习
文章平均质量分 50
饮一盏岁月留香丶
这个作者很懒,什么都没留下…
展开
-
C++智能指针
智能指针的原理RAII 是一种利用对象声明周期来控制程序资源的简单技术,在对象构造时获取资源,接着控制对资源的访问使之在对象的声明周期内始终保持有效,最后在对象析构时释放资源。实际上是将这份资源交给一个对象去管理,让资源能够自动释放。智能指针的原理就是RAII的方法,保证资源能够被自动释放,其次通过operator*()和operator->()的方法,让对象能够按照指针的方式来运行,然后解决浅拷贝的问题,保证资源不会被释放多次引起代码崩溃。auto_ptrauto_ptr 是C++98标准库原创 2021-11-02 23:39:37 · 371 阅读 · 0 评论 -
C++位图及应用
位图位图是用一个比特位来表示一个数据是否存在这一状态的信息,1表示存在,0表示不存在。常用于海量的数据,没有重复的时候,快速判断某个数据是否存在1个字节有8个比特位,就能表示8个数据的状态信息,有N个数据,需要N/8+1个字节。例如,有一个整形数据集合 {1,3,7,4,12,16,19,13,22,18};其中最大数据为22,最小数据为1,首先估算需要大概多少个字节,位图中应包含min到max这个范围中所有数据的状态信息。实际需要22个比特位,需要3个字节的空间。第二步将集合中的数据向位图中进行原创 2021-11-02 18:00:49 · 515 阅读 · 0 评论 -
哈希和哈希桶
概念数据结构中有一类常用于搜索,给定一个元素集合,常见的可用于搜索的算法有遍历,遍历是十分粗暴简单的手段,对于元素的集合没有特殊要求,时间复杂度是O(N)。效率通常较低。二分查找,二分查找要求元素集合有序,时间复杂度为O(logN),二叉搜索树,查找规则简单,但是退化为单支树时间复杂度是O(N),AVL树和红黑树,时间复杂度都是O(logN).上面的这些常用的方法无一例外都有一个关键步骤就是元素的比较,通过比较待查找元素和集合中的元素,来确定该元素在集合中的位置。真实的效率取决于比较的次数。如原创 2021-11-02 15:35:05 · 2067 阅读 · 0 评论 -
红黑树实现
概念红黑树是一种二叉搜索树,在每个节点都上都增加一个字段表示颜色,红色或者黑色,通过一些条件的限制,达到最长路径中节点个数不会超过最短路径中节点个数的两倍。红黑树可以是空树。因此红黑树是一颗近似平衡的二叉搜索树性质:1.红黑树中的节点不是红色就是黑色。2.根节点一定是黑色。3.如果一个节点是红色,那么它的两个孩子节点是黑色。4.对于每个节点,从该节点到其后代所有节点的简单路径中,均包含相同数目的黑色节点。5.每个叶子节点都是黑色的。通过以上性质的约束,最终可以达到最长路径中节点个数不会超过原创 2021-10-28 14:09:57 · 357 阅读 · 0 评论 -
AVL树的实现和插入
二叉搜索树虽然可以提高查找效率,但是在数据有序或近似有序的情况下,二叉搜索树会退化为单枝树,查找效率大大降低,1962年两位俄罗斯数学家联合发明了以一种解决问题的办法,在对二叉搜索树进行插入时,保证每个节点左右子树高度之差的绝对值不超过1,那么就可以降低树的高度,进而减少平均搜索的深度。这种结构的二叉搜索树就是AVL树。AVL树实现节点的创建:节点中需要的成员有,左右孩子指针,增加了一个双亲的指针,表示平衡因子的bf,以及值域data。template<class T>struct原创 2021-10-27 17:56:26 · 436 阅读 · 0 评论 -
二叉搜索树转双向链表
根据描述,排序的双向链表与二叉搜索树的关系可以确定,二叉搜索树的中序遍历结果是一个有序序列,能确定的是中序遍历结果的首元素应是链表的第一个节点。然后就是根据中序遍历结果将树的结构改变为链表的结构,每个节点都有两个指向,一个left一个right,在中序遍历过程中,将拿到的每个节点的left指向比他小的元素中最大的那个,right指向比他大的元素中最小的那个。而在中序遍历过程中,left的指向即是刚刚遍历过的前一个节点,right指向是即将要遍历的后一个节点。class Solution {publi.原创 2021-10-25 02:51:49 · 806 阅读 · 0 评论 -
从前序和中序序列中构造二叉树
做法是将前序序列中依次拿到的元素作为根节点,在中序序列中找根节点的位置,将数分为左子树根节点右子树,递归创建左子树和右子树class Solution {public: TreeNode* _buildTree(vector<int>& preorder,size_t& index,vector<int>& inorder,size_t left,size_t right){ if(left >= right){ .原创 2021-10-25 02:31:10 · 112 阅读 · 0 评论 -
二叉树层序遍历(给你一个二叉树,请你返回其按 层序遍历 得到的节点值)
要求是将层序遍历的结果,第一层中节点的值域存在二维数组的第一个vector中,第二层的存在第二个中。依次继续。创建一个二维数组作为最终输出结果,创建一个队列用来取每层的拿到的值域,创建一个vector对象levelval用来保存每层拿到的值域的集合。以示例为例,第一次3所在的节点入队列,此时队列中节点的个数size更新为1个,从队列中拿出size个节点,将它的值域交给levelval,如果这个节点有左右孩子,则依次将左右孩子入队列,从队列中删除3这个节点,将levelval插进二维数组ret中。接下来..原创 2021-10-25 02:26:34 · 407 阅读 · 0 评论 -
根据二叉树创建字符串
根据示例描述总结一下规律,前序遍历顺序根-左-右先保存根,然后遍历根的左子树,如果左子树为空,要先补一对括号,然后遍历右子树,如果左子树非空,则先用括号扩起左子树,然后递归遍历左子树。右子树如果为空,直接省略,如果非空,用括号括起来,递归遍历右子树class Solution {public: void tree2str(TreeNode* root,string& ret){ if(nullptr == root){ return; .原创 2021-10-25 02:02:12 · 76 阅读 · 0 评论 -
二叉搜索树
性质二叉搜索树又称二叉排序树,是一类具有特殊性质的树。具体体现在二叉搜索树中,每个节点都比它的左孩子大,比它的右孩子小。中序遍历结果是一个有序序列,树中最左侧的节点是序列中最小的元素,最右侧的节点是序列中最大的节点。相关操作及实现创建一个节点创建一个树的节点,给出指向左右孩子的指针以及值为data的值域。template <class T>struct BSTNode { BSTNode(const T& x = T()) :left(nullptr) ,ri原创 2021-10-25 01:51:52 · 290 阅读 · 0 评论 -
C++继承
定义继承是C++中实现代码复用的重要手段,核心思想概括为共性抽取,即将一些相同的特性抽取出来,单独实现成一个类,而把关注点放在不同的特性上,方便在类原有特性上进行扩展,增加新的功能。包含共同特性的类称为父类或基类,扩展出来的新的类称为子类或派生类。继承的特性也体现了面向对象设计的层级结构。继承方式继承方式用来控制不同的方式下,基类中具有不同访问权限的成员在子类中的访问权限。例如public:在public继承方式下,基类中的成员不论公有私有保护的都被继承,基类中私有成员在子类中虽然不可见,但是也原创 2021-10-21 22:56:25 · 216 阅读 · 0 评论 -
栈的压入弹出序列
思路是用栈模拟弹出的过程,pushv来表示入栈序列,popv来表示出栈序列首先如果元素个数不相同肯定不是正确的出栈序列将栈中栈顶元素与出栈序列中的元素进行比较,如果不同,则取入栈序列中下一个元素入栈,如果相同则栈顶元素出栈,与下一个出栈序列中的元素比较。当没有元素可以入栈时,比较剩余的元素,不相同则返回false。全部比较完成都满足条件,则说明是正确的入栈序列。以示例为例子 入栈序列为 1 2 3 4 5 出栈序列为 4 3 5 1 2开始栈为空,取入栈序列第一个元素1入栈,第二趟,栈不为空,将.原创 2021-09-10 01:11:54 · 404 阅读 · 0 评论 -
逆波兰表达式求值
思路是用一个栈来保存所有数字,如果取到一个数字就入栈,如果取到一个算术符,就从栈中取两个数进行运算,并将它们的结果入栈,因为栈的特性,所以先取出的是右操作数,然后才是左操作数。最后栈中应只剩一个结果,返回栈顶元素就是最终结果。[“2”,“1”,"+",“3”,"*"] 以示例为例,2是数字,入栈,1是数字,入栈,下一个取到+,从栈中先取1 再取 2 计算2+1的结果3 入栈,再取3 是数字 入栈,再取是运算符,从栈中取3 和 3 计算3×3结果9入栈,循环结束 返回栈中仅剩的9。class Solut.原创 2021-09-09 20:49:36 · 76 阅读 · 0 评论 -
用队列实现栈
每次插入元素后,调整队列中元素的位置,先获取队头元素并删除,再将该元素插入到队尾。实现先入后出的特性。class MyStack {private: queue<int> q;public: /** Initialize your data structure here. */ MyStack() {} /** Push element x onto stack. */ void push(int x) { int size = q.size(); .原创 2021-09-09 17:22:29 · 68 阅读 · 0 评论 -
用栈实现队列
需要用到两个栈,st1用来入队列,st2用来出队列,将元素入栈的方式进入st1后,从st1中不断取栈顶元素再删除,将取道的元素压入st2中,然后出队列时候从st2中取栈顶元素,就可以满足队列的先入先出特性。class MyQueue { stack<int>st1; stack<int>st2;public: /** Initialize your data structure here. */ MyQueue() {} /** Push.原创 2021-09-09 17:12:26 · 84 阅读 · 0 评论 -
模拟string类的一些常用接口
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<assert.h>#include<algorithm>using namespace std;namespace my{ class string{ public: typedef char* iterator; public: string(const char* str = ""){ if (nullptr == st原创 2021-08-30 13:58:04 · 93 阅读 · 0 评论 -
vector中迭代器失效
什么是迭代器失效迭代器是将指针的方法封装形成的一种新的类型,和指针的特点类似,当指针指向一段不存在的空间时,该指针就是所谓的野指针,再使用迭代器就相当于在操作一个野指针会导致程序崩溃vector迭代器失效的情况所有的插入操作有可能会导致迭代器失效,如push_back,insert,因为插入元素可能会需要扩容,扩容的过程要释放旧空间使用新空间,如果没有给迭代器重新赋值,那迭代器还指向已经被释放掉的旧空间,就会导致迭代器失效。删除操作earse,vector中erase方法的参数是一个迭代器类型的p原创 2021-08-30 00:35:40 · 667 阅读 · 0 评论 -
字符串相加
要将两个存放整形数字的字符串进行相加,可以按照小学学竖式的思路进行。定义一个long_num表示num1 的字符个数 short_num表示num2 的字符个数,通过比较让long_num标记较长的字符串。然后定义一个string类型对象用来存放结果。定义一个carry用来标记是否有进位。从两个字符串的末尾开始拿数字进行相加,如果有进位下一轮相加时要加上进位,每次加完后要将进位标记置为0。循环结束时要判断是否还有进位,有要将进位的1也保存起来,没有则要将保存结果的字符串的首位删掉class So原创 2021-08-26 01:46:32 · 1609 阅读 · 0 评论 -
验证一个字符串是否是回文
因为给的字符串有空格等符号,所以首先判断拿到的字符是否是有效字符,包括大小写字母和数字。然后要将字符串中属于字母的大小写统一起来。begin从前往后拿字符,end从后往前拿字符,拿到有效的字符了就进行比较。class Solution {public: bool isvalidchar(char ch){ if((ch >= '0' && ch <= '9')|| (ch >= 'a' && ch <原创 2021-08-26 01:37:00 · 262 阅读 · 0 评论 -
求字符串中最后一个单词的长度
主要注意输入时候,cin输入是会过滤掉不可见字符如空格,回车。从第一个非空白符开始读,直到空白符或结束为止。单词是以空格分隔的,从后往前找第一个空格的位置,字符串的有效元素个数减去它,因为有效元素个数是从1开始计的,位置pos是0开始的,所以得再减个1,就是最后一个单词长度。#include<iostream>#include<string>using namespace std;void lenth_of_lastword(string& s) { size_原创 2021-08-26 01:31:35 · 253 阅读 · 0 评论 -
找出字符串中只出现一次的字符
sting类中的find和rfind方法,从给定字符串的第一个字符开始,find是从前往后找,rfind是从后往前找,如果最后找到的位置相同,那这个字符是唯一字符,如果位置不相同,这个字符是重复的。#include<iostream>#include<string>using namespace std;void find_once_char( string&s ) { for (size_t i = 0; i < s.size(); i++) { if原创 2021-08-26 01:25:04 · 2233 阅读 · 0 评论 -
深拷贝和浅拷贝实现
浅拷贝在类的默认成员函数的特性中提到,如果类中涉及到资源的管理,那拷贝构造必须要显示提供,否则可能会导致程序崩溃。#include<iostream>using namespace std;class String {public: String(const char* str = "") { _str = new char[strlen(str)] + 1; strcpy(_str, str); } ~String() { delete[]_str; }pri原创 2021-08-24 15:50:57 · 109 阅读 · 0 评论 -
string类及一些常用接口
string中的常用构造方法string(); 构造一个空字符串。string(const char* s);用C风格字符串构造string类的对象string(size_t n,char c);构造一个含有n个字符c的字符串。string(const string& s);拷贝构造方法。//构造方法void Teststring1() { string s; string s1("hello world"); cout << s1 << endl;原创 2021-08-24 01:36:44 · 148 阅读 · 0 评论 -
求1+2+3+...+n要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
思想:①通常我们可以通过循环的方法创造出1~n的每个数字,再累加就可以,因为不能使用循环,所以需要先创建出1到n的所有数字,通过构造函数的特性,每创建一个对象就要调用一次构造函数,在构造函数中记录构造函数调用的次数,再用一个值进行加法。②通过&&运算符,代替循环的方式给出递归出口。①class Sum{public: Sum(){ _count++; _sum+=_count; } Sum(const Sum& s){原创 2021-08-20 02:20:56 · 194 阅读 · 0 评论 -
C++内存管理
C++内存分布内核空间操作系统相关的数据和代码,有访问硬件设备的权限,用户不允许读写。用户空间栈区 :非静态的局部变量,和函数调用相关的一些信息,函数的参数返回值,包括一些寄存器信息等内存映射段 :共享动态内存库,静态库。堆区 :动态内存分配,如malloc realloc calloc开辟的空间数据段 :全局和静态的数据,如函数内部用static修饰的局部变量,不会随着函数结束被释放,生命周期变长。代码段 :不允许被修改的,可执行的代码,只读常量。C++内存管理malloc原创 2021-08-20 01:58:48 · 120 阅读 · 0 评论 -
C++日期类实现
#include<iostream>using namespace std;class Date{public: //构造函数 Date(int year = 1900,int month = 1,int day = 1) :_year(year) ,_month(month) ,_day(day) { //判断参数合法性 if (!(year > 0 &&原创 2021-08-20 00:05:25 · 66 阅读 · 0 评论 -
类和对象总结
1.面向过程和面向对象的区别面向过程的思想重点关注解决问题的过程,主要体现在以函数来驱动程序的进展。面向对象的思想主要将问题分解为多个对象,关注对象之间的交互。2.类和对象的区别类是用来描述对象的一种自定义类型,成员是具有实际属性的一个实体,一个类通过实例化可以创建出多个对象,类定义出来后并没有分配内存空间,只有实例化出对象才开辟空间。3.class关键字class是C++中定义类的关键字,C++兼容C语言,struct也可以定义类,但是class和struct定义出来的类,成员的默认访问权限不同原创 2021-08-17 02:03:56 · 186 阅读 · 0 评论 -
C++中this指针
在C语言中,定义一个日期类型的结构体,并给出设置和打印的方法函数setDate和printDate中,第一个参数是一个结构体类型的指针,用来接收结构体类型变量的地址,通过这个参数就知道要调用这个方法给哪个变量来设置值或是打印。#include<stdio.h>struct Date { int year; int month; int day;};void setDate(struct Date* p,int year, int month, int day) { p->原创 2021-08-15 12:01:06 · 278 阅读 · 0 评论 -
C++函数重载
函数重载的概念是指c++中允许在同一作用域中声明几个功能类似的同名函数,函数的名字相同,参数列表不同。类型,次序,个数。调用原理:同名函数存在的情况下,在编译阶段,编译器会对实参的类型进行推算,根据结果来挑选合适的函数来调用,如果没有合适的类型,会在内部尝试进行隐式类型转换。C++如何支持函数重载C语言和C++在编译过程中,都会对函数名变量名进行重新改编,C和C++有不同的名词修饰规则。在C的编译过程中,函数名的修饰就是在原函数名前加下划线 Bubblesort 被修饰为 _Bubblesort。由原创 2021-08-14 01:18:28 · 98 阅读 · 0 评论