抽象编程(C++)
文章平均质量分 90
gzhosp_redAnt
互联网+医疗践行者
展开
-
C++抽象编程——面向对象(2)——结构体与类
点的表示(Representing points)类的有用属性之一(但并不意味着唯一的一个),就是它们可以将几个相关的信息合并成一个可以作为一个单元进行操作的复合值。作为一个简单的例子,假设我们正在使用坐标始终为整数的x-y网格中的坐标。尽管可以独立地使用x和y值,但更为方便的是定义将x和ay值组合在一起的抽象数据类型(ADT)。在几何体中,这个统一的坐标值对称为一个点,因此使用名称Point对应的原创 2017-05-01 22:15:01 · 2119 阅读 · 0 评论 -
C++抽象编程——递归策略(3)——生成排列数(1)
排列数简介许多文字游戏和谜题需要重新排列一组字母来形成一个单词。因此,如果想编写一个拼字游戏程序,设置一个可以产生一组特定的组合的单词的所有可能的排列是有用的。 在文字游戏中,这样的安排通常被称为变位词(anagrams)。 在数学中,它们被称为排列(permutations)。 假设你想写一个函数:set<string> generatePermutations(string str);用来返回原创 2017-04-21 00:20:02 · 1360 阅读 · 0 评论 -
C++抽象编程——内存管理(1)——动态分配与内存管理
动态分配与内存管理到目前为止,你已经看到了两种将内存分配给变量的机制。当你声明全局常量时,编译器将分配整个程序中已经存在的内存空间。这种分配风格称为静态分配(static allocation),因为变量分配给内存中在程序整个生命周期内保持不变的位置。当你在一个函数中声明一个局部变量时,该变量的空间被分配到栈中.调用函数将内存赋给变量,当函数返回时,该内存被释放。这种分配风格称为自动分配(aut原创 2017-05-24 14:02:45 · 960 阅读 · 0 评论 -
C++抽象编程——算法分析(5)——标准复杂度类
合并算法的计算复杂度现在,我们可以根据分治法实施排序功能。效率如何? 我们当然可以通过对vector的进行排序并对结果进行测试所需时间来测量其效率。但现在开始,我们要从计算复杂度的角度考虑该算法。当你调用合并排序算法来对一组含N个数的vector进行排序的时候,运行时间可以分为下面两个部分:执行当前递归分解操作所需的时间量(The amount of time required to execut原创 2017-05-13 17:19:15 · 1459 阅读 · 0 评论 -
C++抽象编程——面向对象(6)——设计新的类(1)
虽然前面我们定义中的Point类说明了用于定义新类的基本机制,但对于面向对象的理解需要考虑更复杂的示例。所以接下来我们就以一个实例来设计一个有理数的类别,它也可以表示两个数的相除,或者我们可以称他们为分数。接下来我们一步一步的实现它。(所以下面的有理数指的是分数)有理数与浮点数在某些方面,有理数(Rational numbers)与我们以前一直使用的浮点数相似。两种类型的数字都可以表示分数值,如1.原创 2017-05-05 13:15:27 · 947 阅读 · 0 评论 -
C++抽象编程——数据文件的读写与修改
这部分内容我在文件的介绍系列是没有提到的,我当时只是提到了怎么把打开一个文件,怎么再已有数据的文件里处理。其实我们怎么在文件中写入跟读取数据也是很重要的。向文件中写入数据首先我们在 f 盘建一个名为 my.txt 的空文件。在向文件写入数据的时候我们要声明一个输出文件流对象 。就像这样:ofstream outfile;声明了一个输出流的文件对象,名为outfile。我们可以利用其所在的头文件重载的原创 2017-05-24 23:48:12 · 2250 阅读 · 0 评论 -
C++抽象编程——面向对象(7)——设计新的类(2)
上篇我们讲了类设计的5大步骤,那么这次我们就来用实际例子来实现这5大步骤。采用用户的视角(Adopting the client perspective)作为Rational类设计的第一步,你需要考虑客户可能需要哪些功能。在一家大型公司中,您可能会有各种实施团队需要使用合理的数字,并且可以很好地了解他们需要什么。在这种情况下,与这些客户合作并达成一致的设计目标通常很有用。 鉴于我们这里没有具体的客原创 2017-05-05 19:44:39 · 1479 阅读 · 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 · 2237 阅读 · 0 评论 -
C++抽象编程——简单的员工信息管理系统
本来打算今天要写的是快速排序的,那只能等明天了。因为今天突然有个老同学叫我帮她写一个简单的员工管理系统。我3点写到6点30分(没办法,毕竟我也才大二)。最后大致写了个大概,我就把他们的题目拿出来一下吧 实际上我们学校是没有具体讲文件处理的。但是我之前谢写过我们可以用map来处理。所以我就大胆的尝试了一下,没想到就真的可以。下面我把代码奉上:头文件/* *这个文件定义了一个抽象类,里面包含了对原创 2017-05-14 22:46:49 · 5965 阅读 · 4 评论 -
C++抽象编程——完结感言
打算完结这个栏目了谈谈写这个系列之前其实博客这个东西我接触的不久,就是我刚刚上大二的时候接触的。我的第一篇博客写于16年的11月,当时我总是在百度里面找答案,总是能在csdn的博客上找到我想要的答案,于是我就对这个网址产生了很多好感。当时刚刚大一下个学期,我又是那种电脑小白,虽然学的是这个专业的东西。那段时间有很多的项目组说要找我们一起学习开发app,我们都知道Android开发当初很火,作为一个什么都不懂的小白当然原创 2017-05-25 14:48:02 · 1107 阅读 · 0 评论 -
C++抽象编程——算法分析(6)——快速排序算法
即使本章前面介绍的合并排序算法在理论上表现良好,也具有O(N log N)的最差情况复杂度,实际上并没有太多的应用。 相反,目前使用的大多数排序程序都是基于由英国计算机科学家C.A.R.(Tony)Hoare开发的称为Quicksort的算法.快速排序(Quicksort)Quicksort和合并排序都采用分治法。在合并排序算法中,原始向量被分为两部分,每一个被独立排序。 然后将所得到的排序向量合并原创 2017-05-15 17:49:33 · 822 阅读 · 0 评论 -
C++抽象编程——递归策略(3)——foreach语句的简单实现
我想,foreach循环大家都不会陌生,但凡熟悉一点高级的语言的人都是很熟悉的。它遍历每一个元素,并且对它进行处理,方便了很多。我第一次接触foreach的时候,是我在大一的时候学习的C#接触的。很可惜,在java跟C#中都有的这样的方便工具,但是C++是没有的(虽然在C++11中添加了for_each语句,详细用法看: C++抽象编程——STL实战(2)——查找与修改,但是我感觉用法上没那么方便)原创 2017-04-22 16:17:31 · 1134 阅读 · 1 评论 -
C++抽象编程——算法分析(1)——选择排序
在递归中,我们介绍了函数fib(n)的两个不同的递归实现(参见:斐波那契数的分析与拓展),该函数计算第n个斐波那契数。第一个是直接基于数学定义: 事实证明这是非常低效的。第二个实现使用加法序列(additive sequences)的概念来产生效率与传统迭代方法相当的fib(n)版本,表明递归本身不是问题的原因。 即使如此,因为像斐波纳契函数的例子它具有如此高的执行成本,因此递归有时会得到不好原创 2017-05-11 11:53:19 · 934 阅读 · 0 评论 -
C++抽象编程——递归策略——前言
接下来总结的就是递归的核心内容——递归策略(Recursive Strategies),本来我是想接着递归简介就写这个的,但是书本上的很多例子都是利用STL实现的,正如我在STL的心得中讲的,那本书上的很多出口的方法都是它们学校自己的接口提供的,我们要自己去实现。其实我也没想到STL会包含那么多的知识点而已。那个系列确实是写了很多,也很久。但是在另外一个方面,我收获也是不少。 终于可以动手去写这个原创 2017-04-16 13:31:26 · 522 阅读 · 0 评论 -
C++抽象编程——递归策略(2)——子集和问题
虽然Hanoi塔为递归的强大提供了很好的例证,但其作为一个例子,它有效性却受到缺乏实际应用的影响。策略之所以被许多人应用到编程中,是因为它能够解决很多实际问题。如果递归的唯一例子就是像Hanoi塔一样(很容易得出结论),那么递归就仅仅仅是用于解决抽象谜题。但是没有什么东西会离事实很远。其实递归策略为实际问题提出了非常有效的解决方案(最有代表性的是我们以后讲到的的排序问题,因为这一类问题很难以用其他方原创 2017-04-19 21:57:58 · 3386 阅读 · 0 评论 -
C++抽象编程——面向对象(3)——类与接口
将接口与实现分离我们上篇讲的Point类仅在单个源文件的上下文中完全使用该类时才有用(也就是说在其他app中它是不能被使用的)。所以通常在库中导出类定义通常更有用,从而使这些定义可用于更广泛的应用程序。在这种情况下,我们要做的是创建一个point.h文件,作为类的接口和一个单独的point.cpp文件,其中包含相应的实现。 从前面的接口系列可以看出,接口通常仅包含其函数的原型,而不是完整的实现。类原创 2017-05-02 13:28:08 · 1133 阅读 · 0 评论 -
C++抽象编程——算法分析(2)——Big-O表示法
进行如果我们按照上一篇的文章那样的详细分析的问题是您最终得到的信息太多。 虽然有一个公式来预测一个程序将要花多长时间,但是通常可以采取更多的定性措施。 本质上,选择排序的问题在于,将输入向量的大小加倍,将选择排序算法的运行时间增加了四倍,这意味着运行时间比vector中的元素数量的增长快得多。 你可以获得关于算法效率的最有价值的定性观察通常是帮助你了解当问题的规模大小的发生变化算法时的算法性能如何原创 2017-05-11 18:58:34 · 3564 阅读 · 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 · 2928 阅读 · 0 评论 -
C++抽象编程——面向对象(4)——运算符重载与友元函数
运算符重载(Operator overloading)从我们在几个前篇的类的层次介绍中可以知道,C++可以扩展标准运算符,使其适用于新类型。这种技术称为运算符重载。 例如,字符串类重载* + *运算符,使其在应用于字符串时的行为会有所不同。 当C++编译器看到 + 运算符时,它通过查看操作数的类型来决定使用的是哪种运算,如果编译器看到 + 应用于两个整数,它会采用我们一般的数字相加。 如果操作数是字原创 2017-05-03 22:05:12 · 2235 阅读 · 2 评论 -
C++抽象编程——指针(4)——指针的高级应用
将函数作为数值在完成的编程中,函数和数据结构的概念仍然是分开的。函数提供表示算法的方法; 数据结构允许你组织并应用这些算法的信息。这样说来函数已经是算法结构的一部分,而不是数据结构的一部分。然而,能够使用函数作为数据值,通常会使设计有效的接口更容易,因为这样做允许客户端指定操作和数据。函数指针在计算的最初阶段,程序的表现形式使其完全与数据分开。通常,在纸带上打印指令,然后送入机器,然后依次执行指令。原创 2017-05-23 12:16:01 · 1616 阅读 · 1 评论 -
C++抽象编程——自定义strlib文件
今天回顾了一下我最近的C++学习,发现呢我是学了很多的处理问题的方法了。我特地看了一下字符串的总结。然后我把一些很常用的处理字符串的方法都写下来了。在我以往的博客中都可以看到它们。我把它们作为头文件跟实现文件,这样我们前短时间的接口就可以排上用场了,以后我会时不时的把以前的代码封装起来,变为自己的库 这次的库就是我们所谓的“strlib”,里面有去除字符串中的空格函数,有大小写转换。有字符串与数字原创 2017-05-02 22:00:17 · 1543 阅读 · 1 评论 -
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 · 1138 阅读 · 0 评论 -
C++抽象编程——算法分析(4)——合并排序算法
然而,对大型vectory要求的排序,选择排序算法显然不符合任务,因为运行时间与输入大小的平方成比例增加,对于以线性顺序处理向量的元素的大多数排序算法也是如此。 所以要采用定性不同的方法来开发更好的排序算法。强大的分治法奇怪的是,找到更好的排序策略的关键在于认识到选择排序算法的二次行为具有隐藏的好处。二次复杂度的基本特征是,随着问题的大小加倍,运行时间增加了四倍。 然而,相反的情况也是如此。 如果将原创 2017-05-12 15:29:17 · 1407 阅读 · 0 评论 -
C++抽象编程——接口(2)——接口的用途
我们建立了一个接口,但是我们为什么要建立接口?它有什么用呢?我们写在同一个文件里不是更好吗?为什么要那么麻烦?接下来我们就慢慢的探讨吧。出口数据类型(Exporting types)前面部分中描述的error.h接口只是导出一个函数,没有其他的。 以后我们将在C++中使用的大多数接口还导出数据类型。这些类型中的大多数将是类,它们是C++提供的面向对象类型系统的基础。鉴于我们刚刚了解这些,我们就先不出原创 2017-04-24 21:03:54 · 2520 阅读 · 0 评论 -
C++抽象编程——接口(1)——.h文件与.cpp文件的建立
在我们之前写过的程序中,都有这一句:#include <XXX>其中的< XXX >就是一个库。那么这里面到底包含了什么呢?这又是怎么实现的呢?接口与实现(Interfaces and implementations)当我们在C++中定义库时,需要提供两个部分。首先,我们必须定义接口(interface),它提供了客户端使用库所需的信息,但我们要注意留出关于库如何工作的详细信息(即注释)。 其次,要原创 2017-04-24 12:44:43 · 3261 阅读 · 0 评论 -
C++抽象编程——回溯算法(7)——极小化极大算法
极小化极大算法(The minimax algorithm)前面部分描述的技术适用于简单,完全可解决的游戏,如Nim(因为其所有的情况也不算大)。然而,随着游戏变得越来越复杂,很快就无法检查每一个可能的结果。例如,如果你试图通过一切可能的棋牌游戏,即使以现代电脑的速度,这个过程可能需要数十亿年的时间。 然而,不管怎样,尽管有这个限制,电脑在国际象棋方面仍然非常擅长。1997年,IBM的“深蓝色”(D原创 2017-05-10 13:40:13 · 2964 阅读 · 0 评论 -
C++抽象编程——接口(4)——随机接口的设计
说明接口设计原理的最简单的方法是进行简单的设计练习。 为此,我们就来介绍一个能产生随机数的接口 random.h接口的设计过程,这样可以编写看似随机选择的程序。能够模拟随机的行为是有必要掌握的,例如,你想编写一个涉及翻转硬币或滚动骰子的电脑游戏。但在更实际的情况下也是有用的。模拟这种随机事件的程序称为非确定性程序(nondeterministic programs) 让计算机以随机方式运行涉及一定原创 2017-04-27 12:17:12 · 1709 阅读 · 0 评论 -
C++抽象编程——递归策略(3)——生成排列数(2)
课本的原本代码上次我们讲完了生成排列数的原理C++抽象编程——递归简介(3)——生成排列数(1),那么我们接下来就是实现它了。在这篇的前一篇我特意去提了一下foreach语句,就是因为这个文章涉及到。那么我们先看看书上的代码:#include <iostream>#include "set.h"#include "simpio.h"using namespace std;/* Functio原创 2017-04-22 17:10:35 · 1246 阅读 · 0 评论 -
C++抽象编程——储存模式(1)——内存结构
在大多数情况下,我们所写的程序都依赖抽象数据类型来表示复合对象。从实践的角度来看,这个策略是极其常见的。当你以C++等面向对象语言编写程序时,应该尽可能利用库提供的抽象类型的优势,并尽可能远离底层细节的复杂性。因此了解C++如何表示数据是有用的。掌握这些知识可以让我们更好地了解这些抽象类型的工作原理,并帮助我们了解C ++的行为原理。 我们前面提到过的STL使编程变得更加容易。在接下来的内容中,主原创 2017-05-20 19:18:25 · 1471 阅读 · 0 评论 -
C++抽象编程——内存模式(2)——函数调用机制
内存地址在典型计算机的存储器系统中,每个字节由数字地址标识。计算机中的第一个字节编号为0,第二个编号为1,依此类推,直到机器中的字节数减去1。例如,一个小型64KB计算机中的存储器地址将以一个编号为0的字节开始,以一个编号为65,535的字节结束。然而,这些数字表示为十进制值,这不是大多数程序员对地址的看法。鉴于地址与硬件的内部结构密切相关,因此,使用前面介绍的十六进制符号,将地址从地址0000开始原创 2017-05-20 21:14:02 · 1308 阅读 · 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 · 1132 阅读 · 0 评论 -
C++抽象编程——指针(2)——特殊的指针
指向结构体(类)的指针前面部分中的示例仅声明指向基本类型的指针。 在C ++中,将指针与结构或对象结合使用是非常普遍的。 例如,声明:Point pt(3, 4);Point *pp = &pt;声明两个局部变量。变量是pt包含具有坐标值3和4的Point对象。变量pp包含指向同一Point对象的指针。使用基于指针的格式,这些声明产生的内存图如下所示: 从指针pp,你可以使用 * 运算符移动原创 2017-05-21 21:15:52 · 1334 阅读 · 0 评论 -
C++抽象编程——数组(1)——基本用法
数组当我们第一次介绍Vector类时,我们在在数组方面描述了向量。C ++提供了一个内置的数组类型,它基于C ++从C继承的语言模型。由于Vector集合类的统一性更加灵活和方便,所以在新代码中使用数组的原因很少。(在现有应用程序中尽管你一定会遇到矩阵) 在C ++中,数组是具有两个特征的单个数据值的低级集合:一个数组是要被排序的。必须能够按顺序排列阵列的各个组件:这里是第一个,这里是第二个,依原创 2017-05-21 21:17:44 · 1356 阅读 · 0 评论 -
C++抽象编程——数组(2)——数组与指针
有效大小与分配大小虽然sizeof技术允许你确定静态分配的数组的大小,但是有许多应用程序在编写代码时无法知道数组应该有多大,因为实际的元素数量取决于用户的数据。解决选择适当数组大小的问题的一个策略是声明一个你知道的数组大于你需要的数组,然后只使用它的一部分。因此,不是声明数组以使其保存实际数量的元素,而是定义一个常量,指示最大数量的元素,并在该数组的声明中使用该常量。在任何给定使用的程序中,实际数量原创 2017-05-22 13:32:34 · 882 阅读 · 0 评论 -
C++抽象编程——指针(3)——指针运算
指针运算指针与整数之间在C ++中,您可以将运算符+和 - 应用于指针。 结果与某些方面熟悉的算术运算相似,但在其他方面不同。 将这些运算符应用于指针值的过程称为指针运算(pointer arithmetic.)。 指针算术由一个简单的规则定义。如果p是指向数组数组中的初始元素的指针,并且k是整数,则以下标识总是成立: 换句话说,如果将一个整数k添加到指针值,则结果是从原始指针地址开始的数组原创 2017-05-22 17:01:38 · 1186 阅读 · 0 评论 -
C++抽象编程——回溯算法(6)——设计一般的双人游戏
一般的双人游戏程序上一篇博客的中的代码对Nim的解释非常具体。例如,play方法直接负责设置nCoins变量,并在每个play移动后对硬币数量进行更新。然而,双人游戏的总体结构应用的更为普遍。即使不同的游戏需要不同的实现细节,但是使用相同的整体策略可以解决许多游戏。 抽象编程中的一个关键概念是抽象概念(notion of abstraction),它是将问题的一般方面分离出来的过程,使其不再被特定原创 2017-05-10 12:17:12 · 1510 阅读 · 0 评论 -
C++抽象编程——回溯算法(5)——Nim游戏代码及其反思
实话,距离上一篇博客发表完到现在,我为了这个代码写了一个多小时。里面的思维方式让我受益匪浅。很累,但是很开心。下面我就分享出来大家一起看看。我写的时候调试了几次,最后我把我几次调试的过程都写在了注释里面,产生的bug我会一一解释。强烈建议大家自己写一遍。下面的实现,主要的实现是相互递归。Nim游戏代码首先由于代码比较庞大,我们把它封装在一个类上,以Nim头文件命名:Nim.h文件#ifndef _N原创 2017-05-09 23:16:43 · 1211 阅读 · 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 · 2929 阅读 · 0 评论 -
C++抽象编程——面向对象(10)——token扫描器的实现
tokenscanner.h接口界面中的许多方法用于启用更改扫描仪默认行为的选项。例如,我们可以通过初始化像这样的token扫描器忽略输入流中的所有空格:TokenScanner scanner;scanner.ignoreWhitespace();接下来我们的目的是实现下面的一些功能: 方法 作用 构造函数 TokenScanner() TokenScanner(str)原创 2017-05-07 19:13:49 · 2667 阅读 · 0 评论 -
C++学习与基础算法专栏目录
函数C++抽象编程——函数与库C++中的值传递和引用传递接口C++抽象编程——接口(1)——.h文件与.cpp文件的建立 C++抽象编程——接口(2)——接口的用途 C++抽象编程——接口(3)——接口设计的重点 C++抽象编程——接口(4)——随机接口的设计C++抽象编程——接口(5)——随机数算法C++抽象编程——接口(6)——设置随机数种子C++抽象编程——接口总结——随机原创 2017-05-26 00:49:16 · 3374 阅读 · 4 评论