
C++学习与基础算法
文章平均质量分 89
这个栏目主要用于收集自己的C++学习心得,里面的文章全都是原创的,自己动手写,想把最近所写的文章归纳成为一个专栏,让更多人一起学习一起交流。这个月已经坚持写了20篇的原创文章了,希望能有一个自己的专栏。
gzhosp_redAnt
互联网+医疗践行者
展开
-
C++学习与基础算法专栏目录
函数C++抽象编程——函数与库C++中的值传递和引用传递接口C++抽象编程——接口(1)——.h文件与.cpp文件的建立 C++抽象编程——接口(2)——接口的用途 C++抽象编程——接口(3)——接口设计的重点 C++抽象编程——接口(4)——随机接口的设计C++抽象编程——接口(5)——随机数算法C++抽象编程——接口(6)——设置随机数种子C++抽象编程——接口总结——随机原创 2017-05-26 00:49:16 · 3406 阅读 · 4 评论 -
C++抽象编程——完结感言
打算完结这个栏目了谈谈写这个系列之前其实博客这个东西我接触的不久,就是我刚刚上大二的时候接触的。我的第一篇博客写于16年的11月,当时我总是在百度里面找答案,总是能在csdn的博客上找到我想要的答案,于是我就对这个网址产生了很多好感。当时刚刚大一下个学期,我又是那种电脑小白,虽然学的是这个专业的东西。那段时间有很多的项目组说要找我们一起学习开发app,我们都知道Android开发当初很火,作为一个什么都不懂的小白当然原创 2017-05-25 14:48:02 · 1126 阅读 · 0 评论 -
C++抽象编程——数据文件的读写与修改
这部分内容我在文件的介绍系列是没有提到的,我当时只是提到了怎么把打开一个文件,怎么再已有数据的文件里处理。其实我们怎么在文件中写入跟读取数据也是很重要的。向文件中写入数据首先我们在 f 盘建一个名为 my.txt 的空文件。在向文件写入数据的时候我们要声明一个输出文件流对象 。就像这样:ofstream outfile;声明了一个输出流的文件对象,名为outfile。我们可以利用其所在的头文件重载的原创 2017-05-24 23:48:12 · 2283 阅读 · 0 评论 -
C++抽象编程——内存管理(1)——动态分配与内存管理
动态分配与内存管理到目前为止,你已经看到了两种将内存分配给变量的机制。当你声明全局常量时,编译器将分配整个程序中已经存在的内存空间。这种分配风格称为静态分配(static allocation),因为变量分配给内存中在程序整个生命周期内保持不变的位置。当你在一个函数中声明一个局部变量时,该变量的空间被分配到栈中.调用函数将内存赋给变量,当函数返回时,该内存被释放。这种分配风格称为自动分配(aut原创 2017-05-24 14:02:45 · 982 阅读 · 0 评论 -
C++抽象编程——指针(4)——指针的高级应用
将函数作为数值在完成的编程中,函数和数据结构的概念仍然是分开的。函数提供表示算法的方法; 数据结构允许你组织并应用这些算法的信息。这样说来函数已经是算法结构的一部分,而不是数据结构的一部分。然而,能够使用函数作为数据值,通常会使设计有效的接口更容易,因为这样做允许客户端指定操作和数据。函数指针在计算的最初阶段,程序的表现形式使其完全与数据分开。通常,在纸带上打印指令,然后送入机器,然后依次执行指令。原创 2017-05-23 12:16:01 · 1663 阅读 · 1 评论 -
C++抽象编程——指针(3)——指针运算
指针运算指针与整数之间在C ++中,您可以将运算符+和 - 应用于指针。 结果与某些方面熟悉的算术运算相似,但在其他方面不同。 将这些运算符应用于指针值的过程称为指针运算(pointer arithmetic.)。 指针算术由一个简单的规则定义。如果p是指向数组数组中的初始元素的指针,并且k是整数,则以下标识总是成立: 换句话说,如果将一个整数k添加到指针值,则结果是从原始指针地址开始的数组原创 2017-05-22 17:01:38 · 1216 阅读 · 0 评论 -
C++抽象编程——数组(2)——数组与指针
有效大小与分配大小虽然sizeof技术允许你确定静态分配的数组的大小,但是有许多应用程序在编写代码时无法知道数组应该有多大,因为实际的元素数量取决于用户的数据。解决选择适当数组大小的问题的一个策略是声明一个你知道的数组大于你需要的数组,然后只使用它的一部分。因此,不是声明数组以使其保存实际数量的元素,而是定义一个常量,指示最大数量的元素,并在该数组的声明中使用该常量。在任何给定使用的程序中,实际数量原创 2017-05-22 13:32:34 · 915 阅读 · 0 评论 -
C++抽象编程——数组(1)——基本用法
数组当我们第一次介绍Vector类时,我们在在数组方面描述了向量。C ++提供了一个内置的数组类型,它基于C ++从C继承的语言模型。由于Vector集合类的统一性更加灵活和方便,所以在新代码中使用数组的原因很少。(在现有应用程序中尽管你一定会遇到矩阵) 在C ++中,数组是具有两个特征的单个数据值的低级集合:一个数组是要被排序的。必须能够按顺序排列阵列的各个组件:这里是第一个,这里是第二个,依原创 2017-05-21 21:17:44 · 1387 阅读 · 0 评论 -
C++抽象编程——指针(2)——特殊的指针
指向结构体(类)的指针前面部分中的示例仅声明指向基本类型的指针。 在C ++中,将指针与结构或对象结合使用是非常普遍的。 例如,声明:Point pt(3, 4);Point *pp = &pt;声明两个局部变量。变量是pt包含具有坐标值3和4的Point对象。变量pp包含指向同一Point对象的指针。使用基于指针的格式,这些声明产生的内存图如下所示: 从指针pp,你可以使用 * 运算符移动原创 2017-05-21 21:15:52 · 1353 阅读 · 0 评论 -
C++抽象编程——指针(1)——什么是指针?
指针(Pointers)C ++设计背后的原则之一是程序员应该尽可能多地访问由底层硬件提供的工具。因此,C ++使得内存位置具有程序员可见的地址。其值为内存中的地址的数据项称为指针(A data item whose value is an address in memory is called a pointer) 在许多高级编程语言中,指针被通常谨慎使用,因为这些语言提供了消除对指针的大量需求的原创 2017-05-20 22:29:31 · 1162 阅读 · 0 评论 -
C++抽象编程——内存模式(2)——函数调用机制
内存地址在典型计算机的存储器系统中,每个字节由数字地址标识。计算机中的第一个字节编号为0,第二个编号为1,依此类推,直到机器中的字节数减去1。例如,一个小型64KB计算机中的存储器地址将以一个编号为0的字节开始,以一个编号为65,535的字节结束。然而,这些数字表示为十进制值,这不是大多数程序员对地址的看法。鉴于地址与硬件的内部结构密切相关,因此,使用前面介绍的十六进制符号,将地址从地址0000开始原创 2017-05-20 21:14:02 · 1341 阅读 · 0 评论 -
C++抽象编程——储存模式(1)——内存结构
在大多数情况下,我们所写的程序都依赖抽象数据类型来表示复合对象。从实践的角度来看,这个策略是极其常见的。当你以C++等面向对象语言编写程序时,应该尽可能利用库提供的抽象类型的优势,并尽可能远离底层细节的复杂性。因此了解C++如何表示数据是有用的。掌握这些知识可以让我们更好地了解这些抽象类型的工作原理,并帮助我们了解C ++的行为原理。 我们前面提到过的STL使编程变得更加容易。在接下来的内容中,主原创 2017-05-20 19:18:25 · 1500 阅读 · 0 评论 -
C++抽象编程——算法分析(8)——插入排序算法与分析
本来算法分析系列算是写完了(其中我忽略了数学归纳法那一部分内容,因为我觉得我们高中学过就没必要再提一次)。但是教材强调我们要重点看看练习题的第二题。我也看了一下,确实很不错。这道题讨论的是插入排序(insertion sort)算法。题目如下:练习2——插入排序(insertion sort)还有其他几种排序算法表现出选择排序的O(N^2)行为。 其中最重要的是插入排序,其操作如下。你可以依次选择v原创 2017-05-17 13:43:50 · 1006 阅读 · 0 评论 -
C++抽象编程——算法分析(7)——快速排序算法分析
合并排序和Quicksort算法的实际运行时间的头对头比较如下图所示。Quicksort的这种实现往往比合并排序的执行速度快几倍,这是程序员在实践中更频繁地使用它的原因之一。此外,两种算法的运行时间似乎以大致相同的方式增长。 然而,上图所示的实证结果掩盖了重要的一点:只要Quicksort算法选择一个接近于向量中值的枢轴,分区步骤就会将向量划分成大致相等的部分。如果算法选择其枢轴值较差,则两个原创 2017-05-17 10:49:23 · 994 阅读 · 0 评论 -
C++抽象编程——算法分析(6)——快速排序算法
即使本章前面介绍的合并排序算法在理论上表现良好,也具有O(N log N)的最差情况复杂度,实际上并没有太多的应用。 相反,目前使用的大多数排序程序都是基于由英国计算机科学家C.A.R.(Tony)Hoare开发的称为Quicksort的算法.快速排序(Quicksort)Quicksort和合并排序都采用分治法。在合并排序算法中,原始向量被分为两部分,每一个被独立排序。 然后将所得到的排序向量合并原创 2017-05-15 17:49:33 · 855 阅读 · 0 评论 -
C++抽象编程——简单的员工信息管理系统
本来打算今天要写的是快速排序的,那只能等明天了。因为今天突然有个老同学叫我帮她写一个简单的员工管理系统。我3点写到6点30分(没办法,毕竟我也才大二)。最后大致写了个大概,我就把他们的题目拿出来一下吧 实际上我们学校是没有具体讲文件处理的。但是我之前谢写过我们可以用map来处理。所以我就大胆的尝试了一下,没想到就真的可以。下面我把代码奉上:头文件/* *这个文件定义了一个抽象类,里面包含了对原创 2017-05-14 22:46:49 · 6003 阅读 · 4 评论 -
C++抽象编程——算法分析(5)——标准复杂度类
合并算法的计算复杂度现在,我们可以根据分治法实施排序功能。效率如何? 我们当然可以通过对vector的进行排序并对结果进行测试所需时间来测量其效率。但现在开始,我们要从计算复杂度的角度考虑该算法。当你调用合并排序算法来对一组含N个数的vector进行排序的时候,运行时间可以分为下面两个部分:执行当前递归分解操作所需的时间量(The amount of time required to execut原创 2017-05-13 17:19:15 · 1513 阅读 · 0 评论 -
C++抽象编程——算法分析(4)——合并排序算法
然而,对大型vectory要求的排序,选择排序算法显然不符合任务,因为运行时间与输入大小的平方成比例增加,对于以线性顺序处理向量的元素的大多数排序算法也是如此。 所以要采用定性不同的方法来开发更好的排序算法。强大的分治法奇怪的是,找到更好的排序策略的关键在于认识到选择排序算法的二次行为具有隐藏的好处。二次复杂度的基本特征是,随着问题的大小加倍,运行时间增加了四倍。 然而,相反的情况也是如此。 如果将原创 2017-05-12 15:29:17 · 1446 阅读 · 0 评论 -
C++抽象编程——算法分析(3)——深入了解Big-O
从代码中减少计算复杂度下面的代码计算的是vector中的元素的平均值。double average(vector<double> & vec) { int n = vec.size(); double total = 0; for (int i = 0; i < n; i++) { total += vec[i];} return total / n;}你原创 2017-05-11 19:02:27 · 2976 阅读 · 0 评论 -
C++抽象编程——算法分析(2)——Big-O表示法
进行如果我们按照上一篇的文章那样的详细分析的问题是您最终得到的信息太多。 虽然有一个公式来预测一个程序将要花多长时间,但是通常可以采取更多的定性措施。 本质上,选择排序的问题在于,将输入向量的大小加倍,将选择排序算法的运行时间增加了四倍,这意味着运行时间比vector中的元素数量的增长快得多。 你可以获得关于算法效率的最有价值的定性观察通常是帮助你了解当问题的规模大小的发生变化算法时的算法性能如何原创 2017-05-11 18:58:34 · 3623 阅读 · 0 评论 -
C++抽象编程——算法分析(1)——选择排序
在递归中,我们介绍了函数fib(n)的两个不同的递归实现(参见:斐波那契数的分析与拓展),该函数计算第n个斐波那契数。第一个是直接基于数学定义: 事实证明这是非常低效的。第二个实现使用加法序列(additive sequences)的概念来产生效率与传统迭代方法相当的fib(n)版本,表明递归本身不是问题的原因。 即使如此,因为像斐波纳契函数的例子它具有如此高的执行成本,因此递归有时会得到不好原创 2017-05-11 11:53:19 · 960 阅读 · 0 评论 -
C++抽象编程——回溯算法(7)——极小化极大算法
极小化极大算法(The minimax algorithm)前面部分描述的技术适用于简单,完全可解决的游戏,如Nim(因为其所有的情况也不算大)。然而,随着游戏变得越来越复杂,很快就无法检查每一个可能的结果。例如,如果你试图通过一切可能的棋牌游戏,即使以现代电脑的速度,这个过程可能需要数十亿年的时间。 然而,不管怎样,尽管有这个限制,电脑在国际象棋方面仍然非常擅长。1997年,IBM的“深蓝色”(D原创 2017-05-10 13:40:13 · 3040 阅读 · 0 评论 -
C++抽象编程——回溯算法(6)——设计一般的双人游戏
一般的双人游戏程序上一篇博客的中的代码对Nim的解释非常具体。例如,play方法直接负责设置nCoins变量,并在每个play移动后对硬币数量进行更新。然而,双人游戏的总体结构应用的更为普遍。即使不同的游戏需要不同的实现细节,但是使用相同的整体策略可以解决许多游戏。 抽象编程中的一个关键概念是抽象概念(notion of abstraction),它是将问题的一般方面分离出来的过程,使其不再被特定原创 2017-05-10 12:17:12 · 1568 阅读 · 0 评论 -
C++抽象编程——回溯算法(5)——Nim游戏代码及其反思
实话,距离上一篇博客发表完到现在,我为了这个代码写了一个多小时。里面的思维方式让我受益匪浅。很累,但是很开心。下面我就分享出来大家一起看看。我写的时候调试了几次,最后我把我几次调试的过程都写在了注释里面,产生的bug我会一一解释。强烈建议大家自己写一遍。下面的实现,主要的实现是相互递归。Nim游戏代码首先由于代码比较庞大,我们把它封装在一个类上,以Nim头文件命名:Nim.h文件#ifndef _N原创 2017-05-09 23:16:43 · 1250 阅读 · 0 评论 -
C++抽象编程——回溯算法(4)——回溯在游戏中的应用
回溯法与游戏虽然回溯算法是最容易在迷宫的背景下进行说明的,但这个策略却应用的相当普遍。例如,我们可以对大多数双人游戏应用回溯。第一个玩家有一些初步选择。根据选择哪个动作,第二玩家则具有一组特定的响应。这些反应中的每一个都反过来导致了第一个玩家的新选择,这个过程一直持续到游戏结束。游戏中每个回合的不同的可能位置形成一个分支结构,其中每个选项打开越来越多的可能性。 现在我们来说说什么叫回溯算法。回溯算原创 2017-05-09 18:46:33 · 1969 阅读 · 0 评论 -
C++抽象编程——回溯算法(3)——解决迷宫问题
编码解决迷宫问题的算法尽管递归的分解和simple case是我们需要在概念层面上解决问题的所在,但编写完整的程序来导航迷宫需要考虑一些实现细节。例如,我们需要确定一个迷宫本身的表示,例如,怎么确定墙壁在哪里,跟踪当前位置,指示特定正方形被标记,并确定是否已经转义从迷宫在为迷宫设计合适的数据结构时,本身就是一个有趣的编程挑战,它与理解递归算法无关,这是本次讨论的焦点。如果有的话,数据结构的细节可能会原创 2017-05-09 12:57:25 · 2859 阅读 · 0 评论 -
C++抽象编程——回溯算法(2)——准备Direction文件
我记我们在提到方块走动的位置的时候,说过它有三种走法。但是那个时候是因为它的右边是墙壁。但是如果我们把它放在空位上,那么是不是它就有了4种走法?也就是 东南西北。这个时候我们就有必要为方块的走法来制定一个接口,实现这一行为。下面的代码不提供分析,具体的代码分析参考: C++抽象编程——接口(2)——接口的用途Direction.h/*这个文件处理一些关于方位上的应用*/ #ifndef _direc原创 2017-05-08 20:02:04 · 1474 阅读 · 0 评论 -
C++抽象编程——回溯算法(1)——迷宫问题
这部分内容其实是递归策略的一部分,但是里面涉及到了一些面向对象的知识,所以我就先总结了面向对象那一部分。这部分内容不得不说还是很有意思的。迷宫问题曾经在希腊神话时代,地中海的克里特岛被一个名叫米诺斯的暴君统治了(这是一头公牛头和一个人的身体的可怕的野兽)。米诺斯不时要求雅典市青年男女的形式致敬,选中的年轻人将祭祀到牛头人。 为了容纳它,米诺斯迫使他的仆人戴德洛斯(后来通过建造一套翅膀逃离的工程天才)原创 2017-05-08 12:42:40 · 6951 阅读 · 0 评论 -
C++抽象编程——面向对象(10)——token扫描器的实现
tokenscanner.h接口界面中的许多方法用于启用更改扫描仪默认行为的选项。例如,我们可以通过初始化像这样的token扫描器忽略输入流中的所有空格:TokenScanner scanner;scanner.ignoreWhitespace();接下来我们的目的是实现下面的一些功能: 方法 作用 构造函数 TokenScanner() TokenScanner(str)原创 2017-05-07 19:13:49 · 2714 阅读 · 0 评论 -
C++抽象编程——面向对象(9)——token扫描器
token扫描器(Designing a token scanner class)在字符串系列中,最为复杂的字符串处理示例是Pig Latin转换了。 (链接:C++抽象编程——字符串(4)——回文数的检查与Pig Latin游戏)PigLatin程序将问题分解为两个阶段:lineToPigLatin函数将输入划分为单词,然后调用wordToPigLatin将每个单词转换为Pig Latin的句子。原创 2017-05-07 19:11:28 · 2967 阅读 · 0 评论 -
C++抽象编程——面向对象(8)——最终版的Rational文件
Rational.h代码如下:/**这个文件包含了Rational类的声明 ,也包含了这个类的对应的重载运算符的自由*函数的声明。*/ #ifndef _Rational_h#define _Rational_hclass Rational{ public:/**构造函数:Rational*用法: Rational R; Rational R1(n);原创 2017-05-05 22:02:19 · 2278 阅读 · 0 评论 -
C++抽象编程——面向对象(7)——设计新的类(2)
上篇我们讲了类设计的5大步骤,那么这次我们就来用实际例子来实现这5大步骤。采用用户的视角(Adopting the client perspective)作为Rational类设计的第一步,你需要考虑客户可能需要哪些功能。在一家大型公司中,您可能会有各种实施团队需要使用合理的数字,并且可以很好地了解他们需要什么。在这种情况下,与这些客户合作并达成一致的设计目标通常很有用。 鉴于我们这里没有具体的客原创 2017-05-05 19:44:39 · 1505 阅读 · 0 评论 -
C++抽象编程——面向对象(6)——设计新的类(1)
虽然前面我们定义中的Point类说明了用于定义新类的基本机制,但对于面向对象的理解需要考虑更复杂的示例。所以接下来我们就以一个实例来设计一个有理数的类别,它也可以表示两个数的相除,或者我们可以称他们为分数。接下来我们一步一步的实现它。(所以下面的有理数指的是分数)有理数与浮点数在某些方面,有理数(Rational numbers)与我们以前一直使用的浮点数相似。两种类型的数字都可以表示分数值,如1.原创 2017-05-05 13:15:27 · 976 阅读 · 0 评论 -
C++抽象编程——面向对象(5)——最终版的point文件
这里贴上我们讨论了几天的Point类的最终版Point.h#ifndef _Point_h#define _Point_h#include <string>class Point { public:/**构造函数: Point();*用法:Point p * Point pt(xc,yc)* ------------------------*创建一个Point类的对原创 2017-05-03 22:53:25 · 1177 阅读 · 0 评论 -
C++抽象编程——面向对象(4)——运算符重载与友元函数
运算符重载(Operator overloading)从我们在几个前篇的类的层次介绍中可以知道,C++可以扩展标准运算符,使其适用于新类型。这种技术称为运算符重载。 例如,字符串类重载* + *运算符,使其在应用于字符串时的行为会有所不同。 当C++编译器看到 + 运算符时,它通过查看操作数的类型来决定使用的是哪种运算,如果编译器看到 + 应用于两个整数,它会采用我们一般的数字相加。 如果操作数是字原创 2017-05-03 22:05:12 · 2303 阅读 · 2 评论 -
C++抽象编程——自定义strlib文件
今天回顾了一下我最近的C++学习,发现呢我是学了很多的处理问题的方法了。我特地看了一下字符串的总结。然后我把一些很常用的处理字符串的方法都写下来了。在我以往的博客中都可以看到它们。我把它们作为头文件跟实现文件,这样我们前短时间的接口就可以排上用场了,以后我会时不时的把以前的代码封装起来,变为自己的库 这次的库就是我们所谓的“strlib”,里面有去除字符串中的空格函数,有大小写转换。有字符串与数字原创 2017-05-02 22:00:17 · 1604 阅读 · 1 评论 -
C++抽象编程——面向对象(3)——类与接口
将接口与实现分离我们上篇讲的Point类仅在单个源文件的上下文中完全使用该类时才有用(也就是说在其他app中它是不能被使用的)。所以通常在库中导出类定义通常更有用,从而使这些定义可用于更广泛的应用程序。在这种情况下,我们要做的是创建一个point.h文件,作为类的接口和一个单独的point.cpp文件,其中包含相应的实现。 从前面的接口系列可以看出,接口通常仅包含其函数的原型,而不是完整的实现。类原创 2017-05-02 13:28:08 · 1159 阅读 · 0 评论 -
C++抽象编程——面向对象(2)——结构体与类
点的表示(Representing points)类的有用属性之一(但并不意味着唯一的一个),就是它们可以将几个相关的信息合并成一个可以作为一个单元进行操作的复合值。作为一个简单的例子,假设我们正在使用坐标始终为整数的x-y网格中的坐标。尽管可以独立地使用x和y值,但更为方便的是定义将x和ay值组合在一起的抽象数据类型(ADT)。在几何体中,这个统一的坐标值对称为一个点,因此使用名称Point对应的原创 2017-05-01 22:15:01 · 2158 阅读 · 0 评论 -
C++抽象编程——面向对象(1)——类的分级和继承
接下来的系列我们讲讲面向对象,C++的精髓部分。其实我也好久没看了,还是上个学期学过的东西。老师讲的很模糊,但是这本书讲的很不错。下面我就分析一下这本书的总结吧。类的层次结构让我们先回忆一下我们之前提到过的输入输出流,当C++的设计者承担了输入/输出库现代化的任务时,他们选择采用面向对象的方法。该决策的一个含义是讲流库中的数据类型类以类的方式去实现。与表示数据的旧策略相比,类具有许多优点。其中最重要原创 2017-05-01 19:55:55 · 2052 阅读 · 0 评论 -
C++抽象编程——接口总结——随机库代码
我们通过学习random.cpp的代码,主要目标不是为了掌握所有其的复杂性。我们希望做的是知道为什么作为random.h的客户不要了解所有这些细节。 random.cpp中的代码是微妙的,并且包含许多潜在的陷阱,这些陷阱可能会阻碍那些试图从头开始实现这些功能的随意程序员。库接口的主要目的是隐藏这种复杂性。 举个例子,墙可以保护客户免受中世纪地图上可能被标记为“Here Be Dragons”的各原创 2017-04-30 15:20:18 · 1343 阅读 · 2 评论