- 博客(19)
- 收藏
- 关注
原创 shared_ptr原理和简单实现
智能指针不是指针,是对象,但是当作指针来用。原理:对每个所指目标保存一个额外的引用计数,使多个指针可以动态的共享所指对象,即指向一个对象的指针可以增加和减少,当且仅当对象的引用计数为0时才由智能指针调用delete,释放堆上的内存。思路:交给系统来释放内存。智能指针在栈上,所指对象在堆上,系统自动对栈的对象调用析构函数,这时再由智能指针在析构函数里delete,就可以安全释放内存。tips:引用计数不能是成员变量也不能是堆上开辟的空间,而是静态变量,存储映射关系。具体实现:#include <
2020-10-17 18:28:25 664
原创 单链表归并排序
通常,因为单链表不可回头,所以排序可以选择选择排序,冒泡排序。如果在nlogn复杂度下完成,那么可以使用归并排序,思路如下:1.把链表用快慢指针遍历,找到链表中点。2.在链表中点把链表断开,分成两个链表,每个链表再分解。3.当不能分解时,把两个链表合并,变成一个链表。4.继续向上合并,直到链表唯一。//单链表排序(要求时间复杂度nlogn)(归并排序)typedef struct node{ int value; struct node *next;}Node;Node *create
2020-09-06 17:53:35 590
原创 c++用链表实现一个简单的内存池
如同进程池和线程池一样,使用内存池也是为了提高效率。如果不使用内存池,那么频繁的malloc小字节内存不仅会降低运行效率,而且也会产生内存碎片,因此合理使用内存池会让进程执行地又快又好。简单的内存池代码如下://用链表实现一个简单的内存池template <class type>class memory_pool{public: memory_pool() :link(Node()), flag(Flag()) {} //释放空间 ~memory_pool() {
2020-08-10 00:07:58 530 1
原创 c++中new的三种用法
测试类:struct test{ test(int size = 1) { ary = new int[size]; } ~test() { delete[] ary; ary = nullptr; } int *ary;};用法1——当作关键字用,会做2步:1.先开辟空间。2.后调用构造函数。test *a = new test(10);用法2——当函数用,相当于malloc,单纯的开辟空间。test *b = (test *)operator new(size
2020-08-02 14:59:25 3399 2
原创 模版特化和作为萃取器的应用
模版大致分为三种版本:普通版本、部分特化版本、全部特化版本。普通版本:template <class type>void function(type t){}部分特化版本:template <class type>void function(type *t){}全部特化版本:template <>void function<int>(int t){}其中,全部特化版本只能接受一种参数,范围最小;部分特化版本可以接受一类特定的参数,范围
2020-08-01 16:33:06 110
原创 旅行者售货员问题回溯法
不赘述题目了。思路是回溯法,具体如下:假设城市=4,出发地=1城市,那么所有可能如下:1->2->3->4->11->2->4->3->11->3->2->4->11->3->4->2->11->4->3->2->11->4->2->3->1可见,本质是对中间三个城市全排列。剪枝方案如下:先初始化一个最低成本。回溯时计算每一步的成本,如果当前成本比
2020-07-31 17:53:32 1207
原创 n皇后问题回溯法
回溯法类似于穷举法,不过一边穷举一边剪枝,减少计算量。以3皇后为例来说明穷举法和回溯法的异同:穷举法:回溯法:可以看到,每走一步,回溯法都会判断一下,对于已经错误的情况就不往下走,因此回溯法快一些。回溯法代码实现://n皇后问题#define NUMBER 7//皇后个数int sum = 0;//解个数void display(bool chess[NUMBER+1][NUMBER+1])//打印n皇后位置{ for (int row = 1; row <= NUMBER;
2020-07-30 20:04:53 502
原创 哈夫曼树和哈夫曼编码的实现
对于题目和规则不做赘述,进入正题:要点:1.逻辑上哈夫曼树是树结构,但程序的物理结构是数组。2.树构建好后,规定一下左右是0还是1,然后遍历树的每条路径,即可得到每个数据的编码结果。代码如下://哈夫曼编码typedef struct mesage//在优先级队列中用到的结构体{ mesage(int index = 0, int weight = 0) :index(index), weight(weight) {} int index;//下标,用来标识是哪个叶节点 int w
2020-07-29 01:08:20 659
原创 矩阵连乘动态规划
题目我就不赘述了,直接进入正题:假设有矩阵1,2,3…n核心思路是——在[1~n]之间每个位置都做一次划分k,最小结果=先算[1-k]和[k+1-n]两部分最小乘积+最后两个矩阵乘积次数。矩阵[1-n]一共要划分n-1次,相当于一刀一刀挨个儿切过去,每个子问题同样如此,时间复杂度为n^2。可以看到,问题划分为小规模时是分治的思想,但两个小规模之间数据会重复计算好多次,因此采用动态规划,需要中间结果和辅助标记两个二维数组,用空间换时间。具体代码如下://求矩阵连乘void function(int
2020-07-27 19:54:47 391
原创 01背包问题动态规划
问题我就不描述了,直接说步骤。假设背包空间是space,物品个数是number。物品重量是weight,物品价值是value。核心思想——缩小规模,寻找递归表达式。背包空间space下装number个物品的最高价值为:1)如果第number个物品太重,背包为空也放不下,那么规模缩小为——空间space下装number-1个物品的最高价值。2)如果第number个物品能装下,那么分两种情况:1>不装,那么同1)一样,规模缩小为——空间space下装number-1个物品的最高价值。2>
2020-07-26 16:53:43 676
原创 c++中的运算符重载和衍生的思想
运算符重载的概念我们并不陌生,指的是一个运算符在不同环境下有不同的含义。在c语言中就有运算符重载了,只不过不能程序员自定义而已。例如 * 在两个数字之间时意味着乘号,在一个地址的左边时意味着解引用。在c++中引入了类和对象,使程序变得更加复杂。为了阅读程序方面,简化按键次数,c++可以自定义运算符重载了。c++一般对类设置运算符重载,使自定义类型满足和内置类型相同的逻辑。比如设计一个复数类,它可以像整型一样"±*/"等做运算,比调用函数更容易被人理解。运算符重载可以重载单目和双目运算符,不能重载三目运
2020-07-25 12:52:15 212
原创 辗转相除求两个数的最大公约数
辗转相传求两个数的最大公约数#include <math.h>//欧几里得辗转相传求两个数的最大公约数int function(int a, int b){ if (0 == a || 0 == b) return 0; a = abs(a); b = abs(b); if (b > a) { int tmp = a; a = b; b = tmp; } //辗转相除——(b,a mod b)->(a, b) while (b != 0) {
2020-07-11 11:55:49 104
原创 linux中su命令的实现
linux中su命令的实现//su.c#include <stdio.h>#include <sys/types.h>#include <string.h>#include <unistd.h>#include <termios.h>#include <shadow.h>#include <assert.h>#include <pwd.h>#include <stdlib.h>
2020-07-08 23:59:04 944 1
原创 C++中类的编译顺序/过程及注意事项
C++中类的编译顺序/过程及注意事项结论在前:类的编译分4步:1.类名2.成员名称3.成员函数的返回值和形参4.成员函数的函数体注意事项:尽量将类的声明和实现分离。以下面一个简单的例子说明注意事项:class Test;class Test2{public: Test2(Test* p):ptr(p) {} int getTestValue();private: Test* ptr;};class Test{public: const Test2 generate
2020-06-06 20:16:36 2463 1
原创 笔记本电脑选购参考因素
本文为个人观点,仅供参考,如果能帮到你些许,那再好不过了。结论:不盲目追求价格,要按需购买。(不差钱例外)笔记本电脑品牌、型号、套餐多种多样,选择适合自己的着实需要飞一番功夫,以下是几点主要的参考因素。新旧问题:一般来说,买电脑应该买新不买旧,但新电脑普遍变得更薄更轻便,拓展性变弱(内存1可能会焊在主板上,空间可能不足拓展大容量机械硬盘,CPU可能无法更换,接口可能很少需要拓展坞等等)。如果...
2020-03-01 22:37:37 508
原创 运算符重载和转换构造函数相等的情况
运算符重载:发生在类类型中,目的是让表达式看起来更加自然,简化程序员工作量。但本质是函数调用,实质并没有简化。例如创建复数类Complex,两个复数类进行加法。这时不能把自定义的两个类直接相加,可以写一个成员函数:Complex Complex::plus(const Complex tmp);加法是使用频繁最高的,这意味着程序员会频繁地调用函数,要多敲好些键盘——这对程序员来说是会心一...
2019-11-20 23:44:46 335
原创 以自制MyArray对象为例说明对象的概念
C++不建议使用内置数组,提供了功能强大的array和vector。因为内置数组有诸多不便:没有下标越界检查,对两个数组而言不能用==,!=,=等运算符,不能把一个数组赋值给另一个数组等等。而array和vector又有些复杂,自带几十个函数,容易让人看花了眼。为什么我们不自己实现一个精简的数组对象呢?让我们我们模仿array,创建一个自己的int数组"MyArray"对象。先看看测试和运行效果...
2019-10-15 12:43:50 360
原创 统计长整型数字逐位数字的常用方法
当我们看到123,233,66666之类的数字时,人眼读入数字的逻辑是从左往右。当需要检查数字有多长时,对于短数字,我们能一眼看出。对于长数字,则需要从从左到右,仔仔细细心中默念,眼中默看。对于计算机而言,处理数字同理。这里有两种通常方法,一是从高位到低位处理,二是从低位到高位处理。以123456789为例,如果计算机选第一种,从高到低。得到第一位1则需要123456789/(10的8次方)=...
2019-10-12 12:24:21 583
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人