05 2014 档案

摘要:在面向对象系统的设计和开发过程中,对象之间的交互和通信是最为常见的情况,因为对象间的交互本身就是一种通信。在系统比较小的时候,可能对象间的通信不是很多、对象也比较少,我们可以直接硬编码到各个对象的方法中。但是当系统规模变大,对象的量变引起系统复杂度的急剧增加,对象间的通信也变得越来越复杂,这时候我们... 阅读全文
posted @ 2014-05-31 15:27 月轩 阅读(695) 评论(0) 推荐(0) 编辑
摘要:一棵普通树,树中的结点没有指向父节点的指针,求一棵普通树的两个结点的最低公共祖先。代码如下,我太懒没有加注释,大家自己看吧! 1 #include 2 #include 3 #include 4 using namespace std; 5 6 struct TreeNode /... 阅读全文
posted @ 2014-05-30 16:28 月轩 阅读(273) 评论(0) 推荐(0) 编辑
摘要:Memento 模式的关键就是要在不破坏封装行的前提下,捕获并保存一个类的内部状态,这样就可以利用该保存的状态实施恢复操作。 1 /////////Originator.h////////////////////////////////////////// 2 #pragma once 3 #in... 阅读全文
posted @ 2014-05-28 17:17 月轩 阅读(333) 评论(0) 推荐(0) 编辑
摘要:没有啥好解释的啦,关键是要考虑所有的情况,比如正负号,溢出,输入等。 1 enum Status {kValid = 0 , kInvalid}; 2 bool g_nStatus = kValid ; 3 4 int StrToInt(const char* str) 5 { 6 g_n... 阅读全文
posted @ 2014-05-28 15:06 月轩 阅读(148) 评论(0) 推荐(0) 编辑
摘要:Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望能够提供多种形式的表示 (例如以表格进行统计显示、 柱状图统计显示、 百分比统... 阅读全文
posted @ 2014-05-27 20:43 月轩 阅读(297) 评论(0) 推荐(0) 编辑
摘要:不用新的变量,交换两个变量的值。比如有2个变量a , b ,我们希望交换他们的值。下面介绍两种不同的解法:第一种:基于加减法a = a + b ; //先让a等于和b = a - b ; //和减去原来b的值得到原来a的值,赋值给ba = a - b ; //和减去改变后b的值(原来a的值)得到原... 阅读全文
posted @ 2014-05-26 21:41 月轩 阅读(311) 评论(0) 推荐(0) 编辑
摘要:写一个函数,求俩个整数之和,要求函数体内不得使用+、-、*、/ 四则运算符合。看到题目,我们知道,现在只有位运算可以用了,那就用位运算吧。第一步:对2个数的每一位相加,但不进位,我们可以用异或运算完成。第二步:找到进位的位置,并计算进位的值,我们先用与运算可以找到位置,然后左移一位,得到进位的值(比... 阅读全文
posted @ 2014-05-26 21:14 月轩 阅读(315) 评论(1) 推荐(1) 编辑
摘要:C++函数后加关键字throw(something)限制,是对这个函数的异常安全性作出限制。void f() throw() 表示f不允许抛出任何异常,即f是异常安全的。void f() throw(...) 表示f可以抛出任何形式的异常。void f() throw(exceptionType);... 阅读全文
posted @ 2014-05-26 17:37 月轩 阅读(122) 评论(0) 推荐(0) 编辑
摘要:在介绍“ !”运算之前,我们要知道一个变量n,如果n>0,那么我们可以在逻辑上叫它“真”,如果n<=0 ,那么我们可以在逻辑上叫它“假”。n为真时,!n就为假(false),转换为整型值即为0;n为假时,!n就是真(true),转换为整型值即为1;看起来很简单,但是“ !” 运算有一个重要的用处,就... 阅读全文
posted @ 2014-05-26 16:46 月轩 阅读(1087) 评论(0) 推荐(0) 编辑
摘要:把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。解法二:基于循环求骰子点数,比递归算法更加高端大气上档次具体代码如下,有详细注释。 1 ////////////////基于循环求骰子点数////////////////////////////////... 阅读全文
posted @ 2014-05-25 22:29 月轩 阅读(238) 评论(0) 推荐(0) 编辑
摘要:State模式中我们将状态逻辑和动作实现进行分离。允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类;在一个状态即将结束的时候启用下一个状态。 1 /////////state.h//////////////////////////////////////////////////... 阅读全文
posted @ 2014-05-25 16:36 月轩 阅读(316) 评论(0) 推荐(0) 编辑
摘要:可以看到 Strategy 模式和 Template 模式解决了类似的问题,也正如在 Template 模式中分析的,Strategy模式和 Template 模式实际是实现一个抽象接口的两种方式:继承和组合之间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体的实现放在... 阅读全文
posted @ 2014-05-20 21:59 月轩 阅读(347) 评论(0) 推荐(0) 编辑
摘要:从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。从使用角... 阅读全文
posted @ 2014-05-20 21:34 月轩 阅读(290) 评论(0) 推荐(0) 编辑
摘要:把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。 解法一:基于递归求骰子点数。 阅读全文
posted @ 2014-05-20 20:25 月轩 阅读(316) 评论(0) 推荐(0) 编辑
摘要:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。 菜鸟的写法是顺序扫描,时间复杂度是O(n2)。下面给出一种大牛的写法,时间复杂度只需O(n)。 阅读全文
posted @ 2014-05-19 22:51 月轩 阅读(234) 评论(0) 推荐(0) 编辑
摘要:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1). 例如:输入{2,7,3,10,3,2,5,5} , 输出 7 和 10 。 大家首先想到的是顺序扫描法,但是这种方法的时间复杂度是O(n2)。接着大家又会考虑用哈希表的方法,但是空间复杂度不是O(1)。 应该怎么做才能即满足时间复杂度是O(n)又满足空间复杂度是O(1)的要求呢? 我们可以想一想“异或”运算的一个性质。任何一个数字异或它自己都是0 , 那么我们依次异或数组中的每一个数字,得到的结果就会是只出现一次的2个数字的异或结果。 因为这两个数字不同,所以异或结果肯定不为0,且能够区分开这两个数字的地方就是异或结果中为1的位。假设异或结果中从右向左数第n位为1,那么我们就可以把原来数组中的数字按照第n位是否为1分为两部分,每一部分就会只包含一个只出现一次的数字,且其他的数字都是成对出现。接下来只要分别对这两个数组求异或,就能找出每部分只出现一次的数字。 阅读全文
posted @ 2014-05-19 15:11 月轩 阅读(2484) 评论(0) 推荐(0) 编辑
摘要:二叉树中任意左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。 两种解法。 第一种:菜鸟的解法,出现重复遍历,时间复杂度高。 第二种:大神的解法,只遍历一次,高端大气上档次。 阅读全文
posted @ 2014-05-18 17:39 月轩 阅读(278) 评论(0) 推荐(0) 编辑
摘要:多的不解释了,这里有两种解法。 第一种:一般的解法。 第二种:大神的解法,代码简洁高效。 阅读全文
posted @ 2014-05-18 17:26 月轩 阅读(270) 评论(0) 推荐(0) 编辑
摘要:统计一个数字在排序数组中出现的次数。例如输入{2,2,2,2,2,3,5,5}和数字2,输出5. 常规的顺序扫描法时间复杂度是O(n),可以进一步优化。用二分查找的方法进行查找可以把时间复杂度降为O(logn)。 阅读全文
posted @ 2014-05-17 19:16 月轩 阅读(264) 评论(0) 推荐(0) 编辑
摘要:输入两个链表,找出他们的第一个公共结点。思想:我们可以先遍历一次得到分别得到两个链表的长度,然后计算得出长度差n,那么让较长的链表先走n步,然后两个链表一起向后走,直到两个指针指向同一个结点。这个结点就是我们要找的 结点。 阅读全文
posted @ 2014-05-15 22:21 月轩 阅读(389) 评论(0) 推荐(0) 编辑
摘要:在数组中的两个数如果前面一个数大于后面的数字,则这俩个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 例如:数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6)(7,5)(7,4)(6,4)(5,4)。 有两种方法: 第一种:顺序扫描法,时间复杂度是O(n2)。代码略。 第二种:运用归并排序的方法。思想是: 把数组递归的分成子数组,统计出相邻子数组的逆序对,统计过程中需对数组进行排序,防止重复统计。 阅读全文
posted @ 2014-05-15 18:04 月轩 阅读(342) 评论(0) 推荐(0) 编辑
摘要:Template 模式是很简单模式,但是也应用很广的模式。Template 是采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。Template 模式获得一种反向控制结构效果, 这也是面向对象系统的分析和设计中一个原则 DIP(依赖倒置:Dependency Inversion Principles) 。其含义就是父类调用子类的操作(高层模块调用低层模块的操作) ,低层模块实现高层模块声明的接口。这样控制权在父类(高层模块) ,低层模块反而要依赖高层模块。 阅读全文
posted @ 2014-05-15 14:24 月轩 阅读(266) 评论(0) 推荐(0) 编辑
摘要:在字符串中找出第一个只出现一次的字符。如输入:“aabcdc”,则输出b 。 思路:我们可以把数组当做一个简单的哈希表来用,把每个字母的ASCII码值作为在数组中的位置(下标),数组中存储的是该字符出现的次数。这样我们就创建了一个以字符ASCII码为健值的哈希表。 阅读全文
posted @ 2014-05-14 20:31 月轩 阅读(145) 评论(0) 推荐(0) 编辑
摘要:'\0'是C++中字符串的结尾标志,存储在字符串的结尾。 阅读全文
posted @ 2014-05-14 19:45 月轩 阅读(285) 评论(0) 推荐(0) 编辑
摘要:只包含因子2,3,5的数称作丑数。要求按从小到大的顺序输出指定数量的丑数。 有2中方法: 第一种:用穷举法,从最小的1开始判断穷举,是丑数就输出,否则继续循环判断。判断的方法是:如果一个数能被2整除,我们把他连续除以2;如果能被3整除,我们把他连续除以3;如果能被5整除,我们把他连续除以5。如果最后得到的值为1,那么这个数就是丑数。 第二种:用空间换时间,创建一个数组,里面的数字是排好序的丑数,下一个丑数是前面丑数乘以2、3、5得到的大于当前最大丑数的最小一个数。和第一种思路相比,第二种思路不需要在非丑数上做任何计算,因此时间效率会明显提升,但增加了空间消耗。 阅读全文
posted @ 2014-05-14 17:31 月轩 阅读(376) 评论(0) 推荐(0) 编辑
摘要:在以下集中情况下可以用 Proxy模式解决问题: 1)创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF 称之为虚代理(Virtual Proxy); 2)为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网络性能不好的时候,问题尤其突出) ,我们将这个操纵的过程交给一个代理去完成,GoF 称 之为远程代理(Remote Proxy); 3)对对象进行控制访问的时候,比如在 Jive 论坛中不同权限的用户(如管理员、普通用户等)将获得不同层次的操作权限,我们将这个工作交给一个代理去完成,GoF 称之为保 护代理(Protection Proxy)。 4)智能指针(Smart Pointer)。 阅读全文
posted @ 2014-05-14 12:40 月轩 阅读(373) 评论(0) 推荐(0) 编辑
摘要:在软件系统开发中经常回会遇到这样的情况,你实现了一些接口(模块),而这些接口(模块)都分布在几个类中(比如 A和 B、C、D) :A中实现了一些接口,B 中实现一些接口(或者 A代表一个独立模块,B、C、D代表另一些独立模块) 。然后你的客户程序员 (使用你设计的开发人员) 只有很少的要知道你的不同接口到底是在那个类中实现的,绝大多数只是想简单的组合你的 A-D的类的接口,他并不想知道这些接口在哪里实现的。这时我们就要用到Facade 模式,Facade 模式在高层提供了一个统一的接口。 阅读全文
posted @ 2014-05-13 22:09 月轩 阅读(529) 评论(0) 推荐(0) 编辑
摘要:我们先把数组中的整数转换成字符串,在函数compare中定义比较规则,并根据该规则用库函数qsort排列。最后把排序好的数组中的数字依次打印出来,就是该数组中数字拼接出来的最小数字。这种思路的时间复杂度是O(nlogn)。 阅读全文
posted @ 2014-05-13 16:33 月轩 阅读(219) 评论(0) 推荐(0) 编辑
摘要:void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)); 阅读全文
posted @ 2014-05-13 16:23 月轩 阅读(547) 评论(0) 推荐(0) 编辑
摘要:将数组转换为字符串······ 阅读全文
posted @ 2014-05-13 15:12 月轩 阅读(2975) 评论(0) 推荐(0) 编辑
摘要:输入一个整数n,求从1到n这n个数的十进制表示中1出现的次数。例如:输入12,从1到12这些整数中包含1的数字有1,10,11(这里出现了2次)和12, 一共出现了5次。 有2种解法: 第一种:穷举法,从1到n,每个数判断一次,判断的方法是每位除以10,若余数为1,这说明改位含1。复杂度为O(n*logn)。 第二种:递归法,先求最高位出现1的个数,然后去掉最高位递归的求剩下位数中1出现的个数。时间复杂度是O(logn)。 阅读全文
posted @ 2014-05-13 11:51 月轩 阅读(340) 评论(1) 推荐(0) 编辑
摘要:如果一个应用程序使用了太多的对象, 就会造成很大的存储开销。 特别是对于大量轻量级 (细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费。例如一个字母“a”在文档中出现了100000 次,而实际上我们可以让这一万个字母“a”共享一个对象,当然因为在不同的位置可能字母“a”有不同的显示效果(例如字体和大小等设置不同) ,在这种情况我们可以为将对象的状态分为“外部状态”和“内部状态” ,将可以被共享(不会变化)的状态作为内部状态存储在对象中,而外部对象(例如上面提到的字体、大小等)我们可以在适当的时候将外部对象最为参数传递给对象(例如在显示的时候,将字体、大小等信息传递给对象) 。 阅读全文
posted @ 2014-05-11 22:25 月轩 阅读(286) 评论(0) 推荐(0) 编辑
摘要:输入n个数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8 这8个数,则最小的4个数是1,2,3,4. 解法一:O(n)的算法,只有当我们可以修改输入数组时可用 解法二:O(nlogk)的算法,特别适合处理海量数据 阅读全文
posted @ 2014-05-10 20:53 月轩 阅读(154) 评论(0) 推荐(0) 编辑
摘要:set和multiset会根据特定的排序准则,自动将元素排序。两者不同处在于multiset允许元素重复而set不允许。 阅读全文
posted @ 2014-05-10 20:11 月轩 阅读(251) 评论(0) 推荐(0) 编辑
摘要:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如输入数组:{1,3,3,2,3,2,3,3,2}。由于2在数组中出现了5次,超过数组长度的一半,因此要输出2。 有两种解法: 第一种方法是基于快速排序算法的原理,边排序边判断是否符合输出条件。这种方法的代码我因为没有保存,在电脑蓝屏之后全部消失了·······~~~~(_)~~~~ 呜呜。 第二种方法是根据数组特点找出的算法,时间复杂度为O(n),且不用改变数组本身结构。 阅读全文
posted @ 2014-05-10 16:26 月轩 阅读(5950) 评论(0) 推荐(0) 编辑
摘要:八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。 阅读全文
posted @ 2014-05-09 12:37 月轩 阅读(194) 评论(0) 推荐(0) 编辑
摘要:要求:输入一棵二叉排序树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点的指针的指向。 方法一:我们借助一个容器来顺序存储结点的指针,然后改变指针的指向。 方法二:我们边遍历边改变指针的指向。 阅读全文
posted @ 2014-05-07 22:36 月轩 阅读(1122) 评论(0) 推荐(0) 编辑
摘要:流操作符、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、递归函数的形参都推荐使用引用。 阅读全文
posted @ 2014-05-07 20:15 月轩 阅读(111) 评论(0) 推荐(0) 编辑
摘要:实现要点: 1.组合模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。 2.将“客户代码与复杂的对象容器结构”解耦是组合模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。 3.组合模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。 4.组合模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。 5. 客户端尽量不要直接调用树叶类的方法,而是借助其父类(Component)的多态性完成调用,这样可以增加代码的复用性。 使用场景: 以下情况下适用组合模式: 1.你想表示对象 阅读全文
posted @ 2014-05-07 16:21 月轩 阅读(161) 评论(0) 推荐(0) 编辑
摘要:实现一个函数复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。 阅读全文
posted @ 2014-05-06 21:06 月轩 阅读(131) 评论(0) 推荐(0) 编辑
摘要:权限其实就是对类成员的可访问性。 阅读全文
posted @ 2014-05-05 22:17 月轩 阅读(701) 评论(0) 推荐(0) 编辑
摘要:输入一个二叉树,查找该树的所有路径(从根结点到叶结点的通路),并返回和(路径上所有结点值的和)为某一指定值的路径。 阅读全文
posted @ 2014-05-05 22:03 月轩 阅读(176) 评论(0) 推荐(0) 编辑
摘要:在实际软件系统设计和开发中,会经常遇到这种问题:我们为了完成某项工作购买了一个第三方的库来加快开发。 这就带来了一个问题: 我们在应用程序中已经设计好了接口,与这个第三方提供的接口不一致,为了使得这些接口不兼容的类可以在一起工作,Adapter 模式提供了将一个类(第三方库)的接口转化为客户(购买使用者)希望的接口。 阅读全文
posted @ 2014-05-04 21:19 月轩 阅读(230) 评论(0) 推荐(0) 编辑
摘要:要求:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。 算法思想:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的打印操作,直到队列中所有的结点都被打印出来为止。 阅读全文
posted @ 2014-05-04 20:14 月轩 阅读(142) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示