栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

由“树状线条求最长路径问题”浅谈“面向对象”编程的思维方式(AutoCAD.net)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

由“树状线条求最长路径问题”浅谈“面向对象”编程的思维方式(AutoCAD.net)

由“树状线条求最长路径问题”浅谈“面向对象”编程的思维方式(AutoCAD.net)

网友给了这样一个需求:求此图最长路径:

图上为首尾相连个一组线,要求功能是点其中的某一条线,求通过此线的最长一条路径。

 结果如图:

我用各种方法试了一下,感觉别不理想。后来我想了想,发现这就是一棵树啊!根据面向对象的编程思想。我第一步应该是定义一个树对象的类。

期间我发现用树的概念去描述一些问题不太方便,如果加入“家族树”的概念,就容易一些。家族树和树是一个性质的。所以我加入了家族树的概念在里面。

定义类CurvesTree

首先我们可以想到,他应该有个“本人”的属性:是一条Curve。

然后在他下面和他相连的线都可以称为他的孩子。而他的每一个孩子也是一个CurvesTree。所以“孩子们”属性:List< CurvesTree > 孩子们;

然后在他的上面和他相连的线可以称为他的父亲。而他的父亲也是一个CurvesTree。父亲属性:CurvesTree父亲;

我们可以看到,这样的一个类,他是一个递归类。递归类的属性包含他这个类本身。递归类如何构造呢?后面揭晓。

那么作为一个家族树里的一个成员,我们应该知道那些事情呢?

我们应该知道父亲的父亲,以及父亲的父亲的父亲……直到第一代祖先。所以我们需要一个属性,叫做所有先辈。List< CurvesTree > 所有先辈;

显然,我们还需要知道我们的第一代祖先:CurvesTree祖先。

我们还应该知道所有孩子的孩子,那么就是所有后代:List< CurvesTree > 所有后代。

那么,第一代的祖先是没有父亲的,最末的后代是没有孩子的。所以我们定义两个逻辑属性:bool 有孩子。bool 有父亲。

我们回到线的概念上来,一条线上面连着父亲,下面连着孩子们,所以我们要定义两个属性,一个是头,一个是脚。头连着父亲,脚连着孩子们。Point3d 头,Point3d 脚。

需要计算长度,所以我们需要定义一个长度的属性。这个长度不仅仅是本人这条线的长度,还应该包含直到祖先的长度,也就是累计长度。所以定义一个累计长度的属性,double 累计长度。

累计长度如果在没有父亲的时候,就是本人Curve的长度。如果有父亲,则是本人Curve的长度加上父亲的累计长度。

于是我们就可以知道,先找到所有没有孩子的后代,然后找到其中累计长度最长的,那么他的所有先辈加上他自己,也就是从第一代开始最长的一条路径。

到此,问题得到解决。

可以看出来我们定义一个递归类,比写一个递归函数的思路清晰的多。那么这样的递归类应该怎么构建呢。

构造函数的参数应包括如下几个:

public CurvesTree(List curs, Curve cur0, Point3d point底, CurvesTree father)

curs 是全族人,也就是所有的线,

cur0是本人,

point底是连接父亲的点,

father就是他的父亲树。

定义一个全族人的属性接收curs,

赋值本人,

赋值脚,求出头(cur0的另一个端点)。

如果是构建第一代祖先,那么father就是null。

根据father是否是null,赋值父亲,赋值累计长度,赋值所有先辈。

然后关键的一步就是求所有的后代。

我们根据脚点,来找到所有端点重合的线。其中要删掉本人线。剩下的就是他的所有孩子们。

遍历这些孩子们,调用此构造函数本身。把curs,孩子线,这个点,以及this作为father,以上参数,递归此构造函数。于是就产生了一个递归的类。

递归函数的写法就是在函数内部调用函数本身,产生递归。而递归类就是在构造函数中调用构造函数本身,于是就产生了递归类。

我们new这个类的时候,只要把树根的线作为本人线,父亲null,来构造,就产生了一整个树。

之后再写几个方法,求所有的孩子,也是个递归方法。找到所有没有孩子的后代,找到其中累计长度最大的,他的所有先辈加上他自己,就是由树根开始最长的一条路径。

以上就是这个问题的思路。

简单的说一下面向对象的编程思想。要知道并不是你使用一个对象语言就叫做“面向对象”编程。面向对象编程是一种思维模式。和传统的面向过程的编程思想不同。传统的面向过程的编程思想,是着眼于一个过程。想解决一个问题,第一步要做什么,第二步要做什么,一步一步下来,整个的过程,就是面向过程的编程思路。当然在细节上我们离不开过程,需要经常的思考程序过程。但是在整个程序的架构上,我们需要面向对象。这样更容易让问题清晰,直指要害,轻松解决。什么是面向对象的思维模式呢?也就是当我们面对一个问题,首先应该去想象一个事物,这个事物就是一个对象,他是活的。他有自己的个性,有自己的标签,有自己的做事风格。我们抽象出这样的一个对象出来,定义出他的类。设计他的属性,描绘他的动作。就是他长什么样,他有什么动作。他的动作需要什么材料,能产生什么结果。这些是我们思考的内容。这就是面向对象的编程思想。这也是一种思维模式。

理解一个过程可能是非常繁琐,混乱的。而理解一个“事物”,往往很容易。就好比此题,如果我们去想象这个迭代的整个过程,很可能会越想越迷糊。其中可能涉及的很多细节问题会常常出错。而我们把他看做是一棵树,或者一个家族树,一个族谱。那么很多问题就非常好理解了。如果细节上遇到了问题,我们就可以增加一个属性来描述这个问题,增加一个方法来解决这个问题。而不是在一个巨大的迭代函数里上下找来找去。闹的脑子一锅粥。一个好的程序往往就取决于你的类定义的是否优秀。而一个好的程序员必须要具有面向对象的思维模式。这是最基本的。

附我的代码:(因为本人不是专业人士,代码语法写的很潦草,见谅,相信大家能看懂,不美观的地方自己修改吧。)

https://download.csdn.net/download/qq_31512121/77810385

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/955297.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号