`
wangminshe89
  • 浏览: 692976 次
文章分类
社区版块
存档分类
最新评论

太依赖标准库,有时让人变得笨拙

 
阅读更多

现在做程序的时候,开发人员都会偏向使用高级语言,例如Java,C#,PHP,一个很重要的原因就是开发效率高,开发速度快。而之所以这些高级语言能让写代码的速度变得那么快,一个重要原因就是伴随着这些高级语言的强大的接口类库。很多工作都简化成只要引用几个类库,调用几个方法就可以了。

不过太过简单了,有时也未必是好事,比如给数组排序只要 .Sort()就得出结果了,也不用管用冒泡排序,还是用了快速排序,或者因为不能全部加载而用了归并排序。

可是真说回来,谁在意呢。使用标准库,调用标准接口,大家都能看懂,而且经过多年的累积代码也更安全,效率自然也是更优的。

但是若真不在意,有时候也会让程序变得难以阅读,代码变得丑陋,效率也不见得很好。我就在使用C++的时候碰到了这个不幸的事情,太依赖C++的标准容器,导致自己也被绕进去出不来。

 

碰到的问题大致的意思可以归结为这样(实际问题是关于字符串子串的):

有一个城市图,需要统计一个城市到另一个城市的道路条数。有可能一些城市直接不存在道路。一开始就会给出一共有多少个城市(不超过200个)。

 

这很明显是一个动态规划的问题,先要算出城市A和城市B之间的道路条数,如果B和C之间有连通,那么A到B上的道路条数都可以追加到A到C上。

既然可能有城市没有道路,那么我可以用std::list来存储城市,这样方便增删。每个城市到很多城市,那么城市下应该还有一个std::list来存储该城市所能到达的城市。

为了不新建类,我又用到的C++ <utility> 中的std::pair。于是建立的数据结构就像下边这样:

 

#include <list>
#include <utility>
using namespace std;

typedef unsigned char city_index;
//pair/city_index: the end index of city
//pair/int: the counter for city in specific situation
typedef pair<city_index, int> end_count;
typedef list<end_count> end_list;

//pair/city_index: restart, the index of start city
//pair/end_list: the list of indics end city
typedef pair<city_index, end_list> start_ends;
typedef list<start_ends> start_list;
复制代码

看着这样的定义,我还得意了一下:看,用了typedef,定义变量什么的我就不是写那么长的类型名称了。不过其实我错了:看着std::pair 的一堆fisrt和second我根本不知道是什么类型;定义个start_ends变量我也完全想不起来里面到底有什么成员,智能感知也无法告诉我;std::list的iterator又只是双向遍历器,无法直接获取中间某个值,每次都不得不从 it = list.begin() 一直 ++it 下去;因为不停的增与删,连自己了想不清是什么情况增加的又是什么情况删除的,又该如果判定是增还是删又是否已存在。

总之各种纠结的问题,把原本思路很清楚的问题,到实现的时候却因为不合理的数据结构而让实现变得艰难。

 

实现上,根本不需要用到什么标准库容器,也不需要什么std::pair来做个键值,然后一层套一层的让问题变得那么复杂,当然也不需要定义class来封装这些结构。因为类是自己定义的,那些接口方法还得自己实现自己纠结。

只要用二维数组就好了,并不需要什么复杂的数据结构。虽然C++ FAQ上一直强调数组是邪恶的(arrays are evil),强烈推荐我们使用std::vector来代替之。但是只要处理的好,数组是很便利和高效的。

而很多时候在用std::vector时候,我们大部分时间也只是当数组来用调用个[],只是觉得std::vector有个size()可以得到数组的大小,而不需要自己记录。可惜要想用二位数组,我们就只能一层套一层了:std::vector<std::vector<type>>。

 

既然如此,那就直接用个二位数组,就会更加简单易懂:

#define MAX_NO_CITY 256

int roads[MAX_NO_CITY][MAX_NO_CITY];
int number_of_city;
复制代码

 

因为题目说了不会超过200个城市,所以就开个256x256的数组,虽然会浪费点空间,但是实际上这点空间是值得的,比起std::list增删中内存分配消耗的时间,换来的效率要高很多。

而且数组变量的含义也很清晰:第一维表示的是开始城市,第二维代表的是结束城市,数值就是两个城市之间的道路数了,之间没有道路的就是0,不想从中删除。

每次都从1到number_of_city进行遍历即可,不需要考虑太多的条件让问题变得纠结。

 

不过高级语言的类库依然还是开发中的利器,不可不用,更不可抛弃。只是有时候也不能让自己太陷入这种“便利”之中。

1
1
分享到:
评论

相关推荐

    笨拙的手指.cpp

    笨拙的手指.cpp

    showdeps:显示Go软件包的依赖关系

    这可以防止依赖关系图变得过于笨拙,因为您实际上并不在乎外部存储库中的测试依赖关系。 -stdlib标志将包含来自标准库的依赖项。 这些默认情况下是排除在外的,因为对标准库的依赖很少会成为问题。 -T标志使测试...

    gitdrunk:git游戏让您通过编码醉汉而变得笨拙

    地狱,它甚至可以使你成为一个更好的人。 该游戏使那些在周末度过的寂寞时光花在编程和品尝您的国产啤酒上的自杀效果降低了。 我该怎么玩? 这很简单。 所有规则都嵌入在程序中。 为了玩,只需安装游戏并使用...

    Chosen让长并且笨拙的选择框更友好

    Chosen是一款开源的JavaScript插件,由HarvestHQ开发,其目标是让长且复杂的Select控件变得更加用户友好。Chosen通过将多选或单选的下拉列表转化为可搜索、可滚动的列表,大大提升了用户体验。它提供了自定义样式、...

    人机交互论文

    自计算机以一个庞然大物的笨拙体态出现直到现在,它已经越来越紧密地融入了人们的日常生活,...就是连接人和计算机的桥梁,它使人和机器的关系已从“人围着机器转”向“机器围着人转”的方向发展,变得更加自然、和谐。

    雀巢-笨拙精神的胜利.doc

    在中国这片古老而又充满活力的土地上,一家来自瑞士的跨国企业——雀巢公司,以其独特的商业哲学和“笨拙”精神,在短短几十年间取得了令人瞩目的成功。从最初建立双城牛奶制品厂,到如今在瓶装水、咖啡和冰淇淋等多...

    es-stdlib:EcmaScript缺少的标准库

    例如,比较两个数组变得很容易: import esl from 'es-stdlib' console . log ( esl . array . equals ( [ 1 , 2 , 3 ] , [ 1 , 2 , 3 ] ) ) // Prints "true" API文档 大批 isEmpty(self) 返回给定数组是否为空...

    雀巢笨拙精神的胜利.doc

    雀巢公司作为全球食品饮料行业的领军企业,凭借其特有的“笨拙精神”,在中国这个充满挑战与机遇的市场中取得了显著的胜利。本文将详细解读雀巢在中国市场的发展历程和其独到的商业哲学。 雀巢的“笨拙精神”,实则...

    线夹::gem_stone:如果要在“草图”中表达高级布局,则绘图框将变得笨拙。 通过将组件拖放到Bootstrap网格中,在Sketch中创建内容线框

    在传统的草图绘制中,为了表现复杂的网页或应用界面,设计师可能需要使用多个绘图框来规划和组织元素,这可能导致设计过程变得复杂且效率低下。线夹提供了一种解决方案,它利用了Bootstrap的网格系统,使设计师能够...

    csnlp:笨拙的NLP JS库!

    CSNLP-笨拙的NLP JS库! CSNLP是一个JavaScript库,可提供常见的NLP功能,例如令牌化,词干,计算距离等。 用法 npm install csnlp 要求使用node.js var csnlp = require ( 'csnlp' ) API文件 Treebank Tokenizer...

    一个无依赖JavaScript函数库,只做一件事。-Android开发

    只是一个零依赖的npm模块库,只做一件事。 那些笨拙的实用程序库的一种无罪替代。 PWA开发或字节宝贵时的理想选择。 跳转到API,我们欢迎您贡献贡献Just一个零依赖的npm模块库,只做一件事。 那些笨拙的实用程序库的...

    张立宪,,聪明与笨拙

    5. 新库房的特点:新库房重视消防安全,解决了丙二类消防标准的问题,并引入了智能分拣系统,提高了效率。张立宪对于书的爱护体现在他对库房环境的选择上,希望书籍能得到良好的保存。 6. 张立宪的成长背景:张立宪...

    3-4岁幼儿课件 19.笨拙的螃蟹.ppt

    3-4岁幼儿课件 19.笨拙的螃蟹

    备战2020高考语文材料作文素材集锦 34 一个人活得要像一支队伍.doc

    8. **痛苦的价值**:困境和痛苦能激发思考,从中吸取教训,使人在经历后变得更加成熟和智慧。因此,面对困难时,我们应该学会接纳和从中学习。 9. **真实生活的追求**:最终,作者认为活得真实比活得强大更重要,这...

    大班美术活动设计《笨拙的螃蟹》.docx

    "大班美术活动设计《笨拙的螃蟹》" 本资源是关于大班美术活动设计的教学资源,旨在指导幼儿学习和创作连环画。连环画是一种特殊的绘画形式,通过多幅画面连续叙述一个故事或事件的发展过程。活动目标包括引导幼儿...

    SpringBoot_DTO:使用ModelMapper制作的API,而不是笨拙的getset方法,这些方法很容易变得不知所措

    ModelMapper是一个智能对象映射库,它自动化了对象之间的转换过程,使得数据传输对象(DTO,Data Transfer Objects)的创建变得更加简洁。DTO是用于在服务层和视图层之间传输数据的对象,它们通常用于防止暴露过多的...

    nfect:NFECT(Node.js前端构造工具包)允许开发人员通过简单地通过链接方法添加文件和依赖项并为每个文件配置“描述符”来提供文件和依赖项,而无需诸如markupdown或笨拙的设计模式之类的抽象

    愿景是为前端开发人员提供一种机制,以轻松整合许多依赖项(例如常见的页眉和页脚HTML文件,CSS文件以及客户端JavaScript文件),而无需学习和使用特殊的内容标记或笨拙的设计模式。 NFECT还允许开发人员安全地通过...

    asyncjs:稍微不同的 JavaScript 加载器和依赖管理器

    我喜欢延迟加载脚本的想法,但我不喜欢简洁的编码风格和嵌套依赖的笨拙语法。 这就是我创建asyncJS的原因。 与 script.js 和其他脚本加载器相比, asyncJS的优点是 支持内联函数和文本字符串作为 JavaScript ...

    生硬的同义词是什么.pdf

    它通常用来描述物体或身体部位变得不易弯曲、固定不动的状态,也可用于形容人的表情或态度,表现得过于死板和缺乏灵活性。如某人的动作显得“僵硬”,即表示动作不流畅、不自然。 “刻板”则是另一个与“生硬”紧密...

    笨拙的鸟

    "笨拙的鸟"听起来像是一个基于JavaScript开发的趣味游戏,可能类似经典的“Flappy Bird”。在JavaScript领域,我们可以探讨很多相关的话题,包括基础语法、DOM操作、游戏开发框架、动画制作以及用户交互等。 首先,...

Global site tag (gtag.js) - Google Analytics