一个课堂打印案例分析

作者构造了Picture类,汇总需求细节,见招拆招,尤其在“接口设计”这一节里,把自己当成客户,跟自己一问一答(“我希望有些什么操作,如何表述这些操作?”),逐步分析不断复杂的需求,然后抽象出接口,其中不乏作者的经验之谈:要想决定具体操作的形式,有一个好办法,就是试着使用这些操作,从使用的例子推导出操作的定义形式要比从头苦思冥想地发明这些操作容易得多。

  1、最初需求是打印如下文字:

  Paris

  in the

  Spring

  2、构造的Picture类,只需要一个构造函数和一个输出即可完成,如果打印如下文字:

  +-------+

  |Paris  |

  |in the |

  |Spring|

  +-------+

  3、如果使用C式的过程代码,需要做些打印内容的改变可以完成,作者为Picture类添加了一个frame(Picture&)来完成,如果打印内容改变了,我想C式代码作者就会抓头皮了:

  Paris  +-------+

  in the |Paris  |

  Spring|in the |

  |Spring|

  +-------+

  4、Picture类便有了 Picture operator |(const Picture&, const Picture&) 接口,用字符‘|’做两个Picture对象的横向合并,用Picture operator &(const Picture&,const Picture&)接口,用字符‘&’做纵向合并,当我们需要打印如下文字的时候:

  +--------------+

  |+------+      |

  ||Paris |      |

  ||in the|      |

  ||Spring|      |

  |+------+      |

  |Paris +------+|

  |in the|Paris ||

  |Spring|in the||

  |      |Spring||

  |      +------+|

  +--------------+

  我们只需要一句 cout << frame(frame(p) & (p | frame(p))) << endl即可完成。

  下面是Picture类的源码(原书代码中有些许错误,均做过修改和测试):

  1 #include <iostream>

  2

  3

  4  using namespace std;

  5

  6  class Picture

  7 {

  8     friend Picture frame(const Picture&);                      //加框

  9      friend Picture operator&(const Picture&, const Picture&);  //纵向合并

  10      friend Picture operator|(const Picture&, const Picture&);  //横向合并

  11      friend ostream& operator << (ostream& o, const Picture& p);

  12  private:

  13     int height, width;

  14     char* data;

  15     char& position(int row, int col){

  16         return data[row * width + col];

  17     };

  18     char position(int row, int col) const{

  19         return data[row * width + col];

  20     };

  21     void copyblock(int,int,const Picture&);

  22 public:

  23     Picture() : height(0),width(0),data(0){};

  24     Picture(const char* const*, int);

  25     Picture(const Picture& );

  26     ~Picture();

  27     Picture& operator=(const Picture&);

  28     static int max(int m, int n)

  29     {

  30         return m > n ? m : n;

  31     };

  32     void init(int h, int w);

  33     void clear(int , int ,int ,int );

  34 };

  35

  36 ostream&

  37 operator << (ostream& o, const Picture& p)

  38 {

  39     for(int i = 0; i < p.height; ++i)

  40     {

  41         for(int j =0; j < p.width; ++j)

  42             o << p.position(i,j);

  43         o << endl;

  44     }

  45     return o;

  46 };

  47

  48

  49 void Picture::init(int h, int w)

  50 {

  51     height = h;

  52     width = w;

  53     data = new char[height * width];

  54 };

  55

  56 Picture::Picture(const char* const* array, int n)

  57 {

  58     int w = 0;

  59     int i ;

  60     for(i = 0; i < n; i++)

  61         w = Picture::max(w, strlen(array[i]));

  62     init(n,w);

  63     for(i = 0; i < n; i++)

  64     {

  65         const char* src = array[i];

  66         int len = strlen(src);

  67         int j = 0;

  68         while(j < len)

  69         {

  70             position(i,j) = src[j];

  71             ++j;

  72         }

  73         while(j < width)

  74         {

  75             position(i, j) = ' ';

  76             ++j;

  77         }

  78     }

  79 }

  80

  81 Picture::Picture(const Picture& p):

  82          height(p.height), width(p.width),

  83          data(new char[p.height * p.width])

  84 {

  85     copyblock(0,0,p);

  86 }

  87

  88 Picture::~Picture()

  89 {

  90     delete []data;

  91 }

  92

  93 Picture& Picture::operator=(const Picture& p)

  94 {

  95     if(this != &p)

  96     {

  97         delete []data;

  98         init(p.height,p.width);

  99         copyblock(0,0,p);

  100     }

  101     return *this;

  102 }

  103

  104 void Picture::copyblock(int row,int col,const Picture& p)

  105 {

  106     for(int i =0; i < p.height; ++i)

  107     {

  108         for(int j =0; j < p.width; ++j)

  109             position(i+row, j+col) = p.position(i,j);

  110     }

  111 }

  112

  113 void Picture::clear(int h1,int w1,int h2,int w2)

  114 {

  115     for(int r = h1; r < h2; ++r)

  116         for(int c = w1; c < w2; ++c)

  117             position(r,c) = ' ';

  118 }

  119

  120 Picture frame(const Picture& p)

  121 {

  122     Picture r;

  123     r.init(p.height + 2, p.width + 2);

  124     for(int i = 1; i < r.height -1; ++i)

  125     {

  126         r.position(i,0) = '|';

  127         r.position(i, r.width - 1) = '|';

  128     }

  129     for(int j = 1; j < r.width - 1; ++j)

  130     {

  131         r.position(0, j) = '-';

  132         r.position(r.height - 1, j) = '-';

  133     }

  134     r.position(0, 0) = '+';

  135     r.position(0, r.width-1) = '+';

  136     r.position(r.height-1, 0)= '+';

  137     r.position(r.height-1,r.width-1)='+';

  138     r.copyblock(1,1,p);

  139     return r;

  140 }

  141

  142 Picture operator&(const Picture& p, const Picture& q)

  143 {

  144     Picture r;

  145     r.init(p.height + q.height, Picture::max(p.width ,q.width));

  146     r.clear(0,p.width,p.height,r.width);

  147     r.clear(p.height,q.width,r.height,r.width);

  148     r.copyblock(0,0,p);

  149     r.copyblock(p.height,0,q);

  150     return r;

  151 }

  152

  153 Picture operator|(const Picture& p, const Picture& q)

  154 {

  155     Picture r;

  156     r.init(Picture::max(p.height,q.height),p.width + q.width);

  157     r.clear(p.height,0,r.height,q.width);

  158     r.clear(q.height,p.width,r.height,r.width);

  159     r.copyblock(0,0,p);

  160     r.copyblock(0,p.width,q);

  161     return r;

  162 }

  测试代码:

  1 char *init[]= {"Paris","in the","Spring"};

  2 Picture p(init,3);

  3 cout << frame(frame(p) & (p | frame(p))) << endl;

时间: 2024-08-19 20:53:56

一个课堂打印案例分析的相关文章

一个HBase优化案例分析:Facebook Messages系统问题与解决方案

HDFS设计的初衷是为了存储大文件(例如日志文件),面向批处理.顺序I/O的.然而架设在HDFS之上的HBase设计的初衷却是为了解决海量数据的随机读写的请求.把这两种设计初衷截然相反的组件怎么揉在一起的呢?这种分层的结构设计主要是为了使架构更清晰,HBase层和HDFS层各司其职:但是却带来了潜在的性能下降.在很多业务场景中大家使用HBase抱怨最多的两个问题就是:Java GC相关的问题和随机读写性能的问题.Facebook Messages(以下简称FM系统)系统可以说是HBase在onl

IBM一个智慧城市案例分析

我们将介绍一个业务规则管理系统 (BRMS) 的完整的应用程序开发生命周期.我们将探讨 BRMS 架构.规则发现流程.规则应用程序开发和规则维护.这个智慧城市用例涉及到实现一个决策子系统,以在恶劣天气应急事件中在多个城市部门间进行智能协调.这个决策子系统基于 IBM WebSphere® ILOG® JRules 来自动化决策制定流程. 这个文章系列适用于不熟悉业务规则管理系统 (BRMS) 且希望理解创建决策服务的流程的架构师和开发人员.本文将说明选择 BRMS 和 IBM WebSphere

实战案例分析 一个月指数500排名第一

之前就看见了许多实战案例分析的例子,但大多还是一些理论,并没有细节到每一个动作与步骤.今天,我的站刚好上线一个月.今天关键词排名一跃升为第一.看似偶然的事,实是必然.今天和大家分析新站真正快速排名的奥秘,希望其中有某一些改动,某一些细节可以让大家灵感一现,找到自己网站的优化之道. 这个站域名注册时间是6月28日,7月22号上线,迄今为止刚好1个月时间.凤凰古城,指数是5000-6000.凤凰古城住宿,指数500+.其中的热门度不用我说,大家搜索一下便知.当今天打开电脑时,看到网站已经排名第一,说

APT案例分析:一个基于Meterpreter和Windows代理的攻击事件

本文讲的是APT案例分析:一个基于Meterpreter和Windows代理的攻击事件, 前言 几个月前,在只可以通过代理进行访问的公司windows网络中,我对其进行了我开发的模拟定制的APT攻击.在测试过程中,我意外的发现我可以上传https返回类型的meterpreter后门.一开始,我并不确定这个地方存在漏洞,或者这个地方对APT攻击是否起作用.为了验证这个地方是否存在漏洞,我现在需要处理好代理环境. 在对环境做了深入分析之后,我们使用的meterpreter模块(windows/met

丁道师案例分析:执行为王才能想做一个成功的网站

中介交易 SEO诊断 淘宝客 云主机 技术大厅 <汉书·董仲舒传>有云:"临渊羡鱼,不如退而结网."这句话本意是说,你站在河塘边,与其急切地期盼着.幻想着鱼儿到手,还不如回去下功夫结好渔网,这样就不愁得不到鱼.换成我今天要讲的主题就是,看着别人发财,与其自己不断的创想思路,不断的更换不同的方法,还不如静下心来,去执行,脚踏实地先把一种方式实施开来(当然这句话是对于广大正在浮躁中的草根站长说的,牛人自然有其独有的方式获得成功,但是我想大部分的站长还是普通人,正在通过运作网站解

Ajax详解及其案例分析_AJAX相关

1 获得Ajax对象 1.1 问题 如何获得XmlHttpRequest对象. 1.2 方案 区分浏览器,使用不同的获取方式. 1.3 步骤 步骤一: 新建ajax01.html页面 新建一个Web工程,在WebRoot下新建ajax01.html页面.在<script>标记内编写JavaScript代码实现获取Ajax对象. <script type="text/javascript"> /*获取Ajax对象*/ function getXhr(){ var

javascript的理解及经典案例分析_javascript技巧

js的简介: JavaScript是一种能让你的网页更加生动活泼的程式语言,也是目前网页中设计中最容易学又最方便的语言. 你可以利用JavaScript轻易的做出亲切的欢迎讯息.漂亮的数字钟.有广告效果的跑马灯及简易的选举,还可以显示浏览器停留的时间.让这些特殊效果提高网页的可观性. javascript现在可以再网页上做很多很多事情,网页特效,操作dom,html5游戏(基于html5和JavaScript的结合),动画等等特效,还可以实现拉去后台数据(通过ajax),不仅可以做前台还可以做后

PHP数组操作简单案例分析_php技巧

本文实例讲述了PHP数组操作相关技巧.分享给大家供大家参考,具体如下: 这个是一道简单的PHP数组入门题 $Str = "as5454654%^$%^$7675dhasjkdhh12u123123asdasd"; //将上面的统计上面字符串不同字符和出现的次数. 实现方式:将字符串转换成数组,在通过对数组的操作得到相应的结果. $len = strlen($str); //数组存在数组中 $array = array(); for($i=0;$i<$len;$i++) { arr

刘东昇:电商实用EDM案例分析

[亿邦动力网讯]11月23日~24日,在由商务部电子商务和信息化司指导.成都市人民政府和四川省商务厅支持.亿邦动力网主办的第七届中国网上零售年会上,亿业科技CEO刘东昇做了电商实用EDM案例分析,与大家分享了有关邮件营销的相关信息. 下面是亿业科技CEO刘东昇的演讲实录: 刘东昇:我来之前上午和张老师沟通了一下:在中国这种环境下,怎么样让我们的邮件跟垃圾邮件区分开很难.我借此机会把我们怎么样做EMD以及对我们电商有什么好的促进作用讲一讲,讲的过程中我会举一些案例,如果大家有什么问题我也可以给大家