STLlist
- 格式:doc
- 大小:177.00 KB
- 文档页数:30
线性表知识点总结⼀、数据结构思维导图1.算法的特点:明确-算法应该是明确的,毫不含糊的。
它的每个步骤,和它们的输⼊/输出的应明确和必须导致只有⼀个意思。
输⼊-算法应该具有0个或多个明确的定义输⼊输出-算法应该有1个或多个明确定义的输出,并且应当匹配所需的输出。
有限性-算法必须终⽌在有限的之后的步骤。
可能性-应当与可⽤资源的可⾏性。
独⽴-算法应该有逐步的⽅向,应该是独⽴于任何编程代码。
2.基本概念数据——所有能被计算机识别、存储和处理的符号的集合。
数据元素——是数据的基本单位,具有完整确定的实际意义。
数据对象——具有相同性质的数据元素的集合,是数据的⼀个⼦集。
数据结构——是相互之间存在⼀种或多种特定关系的数据元素的集合,表⽰为:Data_Structure=(D, R)数据类型——是⼀个值的集合和定义在该值上的⼀组操作的总称。
抽象数据类型——由⽤户定义的⼀个数学模型与定义在该模型上的⼀组操作,它由基本的数据类型构成。
3.时间复杂度和空间复杂度(1)时间复杂度是指执⾏算法所需要的计算⼯作量。
时间复杂度是⼀个函数,它定性描述了该算法的运⾏时间。
这是⼀个关于代表算法输⼊值的字符串的长度的函数。
时间复杂度常⽤⼤O符号表述,不包括这个函数的低阶项和⾸项系数。
(2)空间复杂度是指执⾏这个算法所需要的内存空间。
空间复杂度需要考虑在运⾏过程中为局部变量分配的存储空间的⼤⼩,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。
常见的时间复杂度有:常数阶O(1),对数阶O(log2 n),线性阶O(n),线性对数阶O(n log2 n),平⽅阶O(n^2),⽴⽅阶O(n^3)k次⽅阶O(n^K),指数阶O(2^n)。
随着n的不断增⼤,时间复杂度不断增⼤,算法花费时间越多。
⼆、线性表思维导图(⼀)基础知识:1.元素-存储在数组中的每个项被称为⼀个元素2.索引-在⼀个数组元素所在的每个位置,是具有⼀个⽤于识别该元素的数值索引。
外贸物流中一些常见英文的缩写。
1 CFR(cost and freight) 成本加运费价2 T/T(telegraphic transfer) 电汇3 D/P(document against payment) 付款交单4 D/A (document against acceptance) 承兑交单5 C.O (certificate of origin) 一般原产地证6 G.S.P.(generalized system of preferences) 普惠制7 CTN/CTNS(carton/cartons) 纸箱8 PCE/PCS(piece/pieces) 只、个、支等9 DL/DLS(dollar/dollars) 美元10 DOZ/DZ(dozen) 一打11 PKG(package) 一包,一捆,一扎,一件等12 WT(weight) 重量13 G.W.(gross weight) 毛重14 N.W.(net weight) 净重15 C/D (customs declaration) 报关单16 EA(each) 每个,各17 W (with) 具有18 w/o(without) 没有19 FAC(facsimile) 传真20 IMP(import) 进口21 EXP(export) 出口22 MAX (maximum) 最大的、最大限度的23 MIN (minimum) 最小的,最低限度24 M 或MED (medium) 中等,中级的25 M/V(merchant vessel) 商船26 S.S(steamship) 船运27 MT或M/T(metric ton) 公吨28 DOC (document) 文件、单据29 INT(international) 国际的30 P/L (packing list) 装箱单、明细表31 INV (invoice) 发票32 PCT (percent) 百分比33 REF (reference) 参考、查价34 EMS (express mail special) 特快传递35 STL.(style) 式样、款式、类型36 T或LTX或TX(telex) 电传37 RMB(renminbi) 人民币38 S/M (shipping marks) 装船标记39 PR或PRC(price) 价格40 PUR (purchase) 购买、购货41 S/C(sales contract) 销售确认书42 L/C (letter of credit) 信用证43 B/L (bill of lading) 提单44 FOB (free on board) 离岸价45 CIF (cost,insurance&freight) 成本、保险加运费价AAA制自动许可制AAC 亚非会议A.A.R 保综合险(一切险)ABCコ-ドABC商业密码ac. 英亩a/c(或A/C) 银行往来存款acpt 承兑;接受a/cs pay. 应付帐款a/cs rec. 应收帐款ACU 亚洲清算同盟A/D 出票后ADB 亚洲开发银行a.f. 预付运费AFA 自动外汇分配制度AFDB 非洲开发银行A.F.E.B. 核准的外汇银行agcy 代理公司agt. 代理人AIQ制自动进口配额制A.M. 互相保险A.N. 到货通知A/P 委托付款证A/P 委托购买证A/P 附加保险费A/P 付讫APO 亚洲生产率组织APU 亚洲支付同盟A/R 综合险,一切险A/S 销货帐单A/S 见票后A/S 见票即付ASEAN 东南亚国家联盟ASP 美国销售价格ATAカルネ暂时许可簿册,临时过境证A.T.L. 实际全损A/V 从价A/W 实际重量A.W.B. 空运单BB/Aレ-ト银行承兑利率B/B 买入汇票B/C 托收汇票B/D 银行贴现B/D 银行汇票B/E 入港申报单B/E 汇票BETRO 英国出口贸易研究组织BIS 国际清算银行B/G 保税货物B/L 提单B/N 钞票B/N 交货记录B.O. 分公司B.P. 应付票据B.R. 应收票据B/S 再进口免税证B/St 即票BTN 布鲁塞尔税则分类B.T.T. 银行电汇CC.A.D. 凭单付款C.B.D. 交货前付款C.B.S. 装船前预付货款C/C 商会C.C. 时价CCC 关税合作理事会CCCN 关税合作理事会税则分类表C.F.S. 集装箱货运站C.H. 货舱C.H. 票据交换所C.H. 海关Chq. 支票C.I. 领事签证发票C/I 保险证书CIF関税込条件成本,保险费,运费加关税条件CIF条件成本,保险加运费条件CIF通関费用込条件成本,保险费,运费和一切进口费用条件CIF&C条件成本,保险费,运费加佣金条件CIFに関する国际统一规则CIF买卖契约统一规则C.L.货物「コ」(集装箱)整箱货CLP 装箱单C/N 发货通知单C/N 贷记通知书C/O 转交C/O 产地证明书C.O.D. 交货付款C.O.F.C. 平板车装运集装箱COGSA 海洋货物运输法cont. 合同c.o.s. 装船时付款C/P 租船合同C.Q.D. 习惯快速装卸C.T. 载货吨位C.t.l. 推定全损C.W.O. 订货付款DD/A 承兑交单D/C 绕航条款D/C 贴现,折扣D/D 码头交货D/D 即期汇票,跟单汇票D/F 空舱运费D/M 速遣费D/N 借记通知D/O 交货单,出货单D/P 付款交单D.P.V. 完税价格D.R. 码头收据d.t. 交货时间DW 载重量D/W 码头栈单D.W.T. 载重吨位DWTC 载货吨EECAFE(UN) 亚洲及远东经济委员会ECE 欧洲经济委员会ECM 欧洲共同市场E/D 出口申报单EEC 欧洲经济共同体EFTA 欧洲自由贸易联盟E/L 出口许可证EMA 欧洲货币协定EPU 欧洲支付同盟ESCAP(UN) 亚洲及太平洋经济社会委员会ETA 预计到达时间TTD 预计离港时间ETE 预计开航时间exch. 兑换,汇兑;交易所exd 已查,已检验作者:夜半一点钟2006-2-9 02:38 回复此发言-------------------------------------------------------------------------------- 2 国际贸易术语英文缩写FFA 外汇配额制度F.A 货物运送代理行f.a.a. 一切海损不赔F.A.K.「コ」同一费率F.A.Q. 良好平均质量,大路货F.A.S. 启运地船边交大货价F.B. 运费单F.B.E. 外国汇票FC&S约款「保」捕获拘留除外条款FCL 整箱货FCL 整装集装箱f/d 自由港FEFC 远东水脚公会f.f.a 船边交货f.g.a 共同海损不赔F/L 运价表F.M. 不可抗力f.q. 实盘FOB 船上交货价FOR 火车上交货价FOT 卡车上交货价F.P.A. 单独海损不赔frt.pd. 运费已付frt.ppd. 运费预付F.W.D. 淡水损失fy.pd. 付讫GG.A 共同海损g.b.q. 故障货物G.M.Q. 上好可销品质G.N.P. 国民生产总值Gr.R.T. 注册总吨grs.wt. 毛重GT 总吨位G.T.C. 撤销前有效G.T.M. 本月中有效G.T.W. 本周中有效HHKD 港币H.O. 总公司Hr 港口II.B.R.D. 联合国国际复兴开发银行I.C.C. 国际商会ICHCA 国际货物装卸协调联合会I/D 进口申报单IFC 国际金融公司I/L 进口许可IMF 国际货币基金组织IMF借款国际货币基金信贷IMF引出権国际货币基金组织提款权INCOTERMS 国际贸易条件解释通则INTRADE 国际贸易发展协会I.O.P. 不论损失率如何全部赔偿IQ制进口配额制I/R 汇入汇款ITC 国际贸易中心ITC 国际贸易宪章ITO 国际贸易组织IUMI 国际海上保险联盟LL/A 卸货代理行L/A 授权书LASH 载驳船L/C 信用证L/G 保证书L/H 质押证书L/I 赔偿保证书Lkg 漏损LT 书信电报l.t.,L/T 长吨,英吨LWL 载重线Mmarg. 保证金m/d 出票日后……个月(付款)MEA 制造厂商外销代理人M/F 舱单,载货单MFN 最惠国M.I 海上保险min. 最低限度M.I.P. 海上保险单mk 包装标志M/Lクロ-ズ溢短装条款M/O 汇款单M/R 大副收据M/T 公吨Nn/a 拒绝承兑,不接受N/C 新租船契约N.C.V. 无商业价值N/F (银行)无存款N.G. 纯收益N.L. 纯损,净损失N/M 无装运标志N.N. (票据)无签名N/R 备装通知NRクロ-ズ免责条款N/S 无存货N.S.F. 存款不足NTB 非关税壁垒N.U. 船名不详NW,N.wt. 净重OOAEC 亚洲经济合作组织O/B 开证银行O/C 货港未定租船合同O/D 见票即付O.E.C.D. 经济合作与发展组织O.F. 海运运费O.G.L. 公开一般许可证OR 船舶所有人承担风险O/R 汇出汇款ovld. 过载PP/A 单独海损P.&L. 损益payt. 支付,付款pd 付讫,通过P.D. 港务费pm. 保费P/N 期票P.O.C. 停靠港P.O.D. 交货时付款P.O.R. 避难港QQ 检疫Q/D 快递件,快速装卸qlty. 品质quotn 报价,行市quty. 数量Rrd. 收讫R/D 与出票人接洽R.D.C. 碰撞条款rept. 收据R.F.W.D. 雨淋淡水损害SS.C. 救助费S.D. 海损S.D. 装运单据s.d. 交货不足S/D 即期汇票SDR 特别提款权sgd 已签署SHEX 星期日和假日除外SHINC 星期日和假日包括在内sig. 签署SITC 标准国际贸易分类S.L. 海难救助损失S/N 装船通知单S.O. 卖方选择S/O 装货单百度文库SP 起运港spec. 说明书,规格S.R. 本船收货单S.R. 货运收据,装货收据S/S 轮船S.S.B.C. 沉没,触碓,火灾和碰撞S.T. 短吨stg. 英镑stor. 存仓费,栈租Ttfr. 转帐,过户T.L. 全损T.L.O. 仅保全损T.M.O. 电汇票T.P.N.D. 偷窃及提货不着险T/R 信托收据T/T 电汇T.T.B. 买入电汇T.T.P. 应付电汇T.T.R. 应收电汇WW.A. 承保单独海损,水渍险W/R 战争险w.r. 仓库收据W/W 仓单W/Wクロ-ズ仓至仓条款W.W.D. 晴天工作日17 11。
initialize_listInitialize_list是C++11标准中新增的一种初始化方式,主要用于初始化数组和STL容器,它的出现是为了解决传统初始化方式在语法、实现上存在的一些问题,使得程序员更加方便、高效的进行初始化操作。
一、传统初始化方式的问题在C++11之前,我们通常采用以下两种方式进行数组和容器的初始化:1. 显式初始化C++支持显式初始化,例如:int arr[5] = {1, 2, 3, 4, 5};这是一种很直观、易于理解的方式,将数组arr的前五个元素分别初始化为1、2、3、4、5。
但是这种方式存在以下问题:- 不能省略元素的个数。
例如,如果一个数组有10000个元素,你必须手动输入10000个元素的值,这是不现实的。
- 不能使用变量。
如果我们想要将数组的元素定义为一些计算结果的变量,这种方式也无法实现。
2. 拷贝初始化拷贝初始化是一种将一个对象拷贝到另一个对象中的初始化方式,例如:std::vector<int> vec; std::vector<int> otherVec = vec;这种方式可以使用容器的copy构造函数,将一个容器复制到另一个容器中。
但是它也存在以下问题:- 使用copy构造函数,需要容器的类型必须相同,否则无法拷贝。
- 对于数组的拷贝初始化,需要手动进行循环,一一拷贝数组元素,是一种效率较低的方式。
由于这些问题的存在,C++11标准中引入了Initialize_list初始化方式,解决了许多之前的问题。
二、Initialize_list的基本语法Initialize_list初始化方式使用一对花括号来构造,其中包含多个元素,元素之间使用逗号隔开。
例如:int arr[] = {1, 2, 3, 4, 5};这种方式就是用Initialize_list初始化了一个5个元素的数组,分别为1、2、3、4、5。
Initialize_list还可以用于容器的初始化,例如:std::vector<int> vec{1, 2, 3, 4, 5};这种方式也是Initialize_list初始化,它直接将{1, 2, 3, 4, 5}作为容器的元素进行添加。
一、容器容器是随着面向对象语言的诞生而提出的,容器类在面向对象语言中特别重要,甚至它被认为是早期面向对象语言的基础。
在现在几乎所有的面向对象的语言中也都伴随着一个容器集,在C++ 中,就是标准模板库(STL )。
其特点如下:vector ,deque 和 list顺序性容器:向量 vector :是一个线性顺序结构。
相当于数组,但其大小可以不预先指定,并且自动扩展。
它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。
在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。
当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作:首先,vector 会申请一块更大的内存块;然后,将原来的数据拷贝到新的内存块中;其次,销毁掉原内存块中的对象(调用对象的析构函数);最后,将原来的内存空间释放掉。
如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。
所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。
vector 的特点:(1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。
即它可以像数组一样操作,并且可以进行动态操作。
通常体现在push_back() pop_back() 。
(2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at()(3) 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。
(4) 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。
竭诚为您提供优质文档/双击可除c语言怎么输出表格篇一:c语言表格c语言c语言关键字c语言运算符算术运算符字符常数扩展表示法运算符的优先级与结合性printf函数的输出格式符scanf函数的输入格式控制符篇二:c语言顺序表实现完整版#include#include#include#definelist_init_size100#definelistincRement10typedefintelemtype;typedefintstatus;typedefstruct{elemtype*elem;intlength;intlistsize;}sqlist;//定义顺序表类型statusinitlist_sq(sqlistl.length=0;l.listsize=list_init_size;return1;}voidcreatelist(sqlistprintf("请输入你要创建的顺序表元素个数"); scanf("%d",printf("请输入你要创建的顺序表:\n");for(i=0;i scanf("%d",}voidprint(sqlistfor(i=0;i printf("%3d",l.elem[i]);}statuslocation(sqlistl,elemtypee)//查找元素的位置{inti=0;while(l.elem[i]!=eif(i>l.length)return-1;elsereturni+1;//因为c语言是从下标0开始的当i=0时实际上是顺序表的第i+1个元素}statuslistinsert_sq(sqlistif(il.length+1)return0;if(l.length>=l.listsize){newbase=(elemtype*)realloc(l.elem,(l.listsize+listi ncRement)*sizeof(elemtype));l.elem=newbase;l.listsize+=listincRement;}q=for(p=p>=q;--p)*(p+1)=*p;*q=e;++l.length;return1;}statuslistdelect_sq(sqlistif(il.length))return0;p=e=*p;q=l.elem+l.length-1;for(++p;p *(p-1)=*p;--l.length;return1;}voidcombine(sqlistla,sqlistlb,sqlistpa=la.elem;pb=lb.elem;lc.listsize=lc.length=la.length+lb.length;pc=lc.elem=(elemtype*)malloc(lc.listsize*sizeof(elemtype));pa_last=la.elem+la.length-1;pb_last=lb.elem+lb.length-1;while(pa else*pc++=*pb++;}while(pa *pc++=*pa++;while(pb *pc++=*pb++;}voidmain(){sqlistla,lb,lc,ld;inti,j;elemtypee;initlist_sq(la);createlist(la);print(la);printf("请输入要查找的元素:\n");scanf("%d",j=location(la,e);printf("该元素的位置为%d\n",j);printf("请输入要插入的位置和元素:\n");scanf("%d%d",listinsert_sq(la,i,e);printf("输出插入后的顺序表:\n");print(la);printf("请输入要删除的位置:\n");scanf("%d",listdelect_sq(la,i,e);printf("删除的那个元素是:%d\n",e);printf("输出删除后的顺序表:\n");print(la);initlist_sq(lb);createlist(lb);print(lb);initlist_sq(lc);createlist(lc);print(lc);initlist_sq(ld);combine(lb,lc,ld);printf("合并后的顺序表为:\n");print(ld);}篇三:使用c语言读出excel表格课程设计课程设计(大作业)报告信息技术学院昆明学院课程设计(大作业)任务书课程设计(大作业)报告一、题目分析简单综合成绩计算系统二、总体设计1.到底包括哪些成绩。
std::list简介及其使⽤注:std::list C++11标准list概述template <class T, class Alloc = allocator<T> > class list; list是⼀种序列容器,它允许在序列中的任意位置进⾏常数时间的插⼊和删除操作,并可以在两个⽅向上进⾏迭代(遍历)。
list容器是基于双链表实现的,可以将其包含的每个元素存储在不同且不相关的存储位置上。
通过链接到前⼀个元素和后⼀个元素的每个元素的关联关系在链表内部保持顺序。
list与forward_list⾮常相似:主要的区别是forward_list对象是单向链表,因此只能单向(forward)迭代(遍历),占⽤空间更⼩也更⾼效。
与其他基本的标准序列容器(array、vector和deque)相⽐,list在任何位置进⾏插⼊、获取和移动元素等操作⽅⾯都表现得更好,因此在使⽤这些操作的算法中也表现得更好,⽐如排序算法。
与其他序列容器相⽐,list和forward_list的主要缺点是它们⽆法使⽤元素位置对元素直接访问。
例如,要访问list中的第6个元素,必须从已知位置(如开始或结束)遍历到该位置,需要花费的时间与这些位置之间的距离呈线性关系。
它们还要消耗⼀些额外的内存来保存将每个元素关联起来的链接信息(也就是指针)。
容器属性顺序存储 顺序容器中的元素按照严格的线性顺序存储。
各个元素通过使⽤它们在这个序列中的位置来访问。
双向链表 每个元素都保存了如何定位下⼀个和前⼀个元素的信息,允许在特定元素之前或之后(甚⾄在整个范围内)进⾏常数时间的插⼊和删除操作,但不允许直接随机访问。
分配器 容器使⽤allocator对象来动态处理其存储需求。
模板参数T 元素的类型。
别名为成员类型 list :: value_type。
Alloc ⽤于定义分配模型的分配器对象的类型。
默认情况下,使⽤allocator类模板,该模板定义最简单的内存分配模型,并且与值⽆关。
/* initializer_list是C++11新增的,可以使用它来初始化STL: 例如:std::vector payments {45.9,39.3,19.59,89.1}; 上述声明与下述代码等价(这里显式的将列表指定为构造函数参数): std::vector payments ({45.9,39.3,19.59,89.1});
在C++11 可以使用 {} 而不是 () 来调用类的构造函数: shared_ptrpd{new double}; //ok to use {} instead of () */
/* 提供initializer_list类的初衷,旨在能够将一系列的值换递给构造函数或其他函数。 注意:initializer_list的迭代器类型为const,因此不能修改initializer_list中的值。 即不能这么做: *dl.begin() = 20.0; 错误做法。 但可以将一个initializer_list赋给另一个initializer_list: dl={16.0,25.0,36.0,49.0,64.0}; */
#include #include
double sum(std::initializer_listil); double average(conststd::initializer_list&ril);
int main(intargc,char **argv){ usingstd::cout; usingstd::endl;
cout<<"List 1:sum = "<
/* c1.h (程序名) */#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等*/#include<limits.h> /* INT_MAX等*/#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h> /* exit() *//* 函数结果状态代码*/#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/ typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/ typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE *//* algo2-1.c 实现算法2.1的程序*/#include"c1.h"typedef int ElemType;#include"c2-1.h"/*c2-1.h 线性表的动态分配顺序存储结构*/#define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量*/#define LISTINCREMENT 2/* 线性表存储空间的分配增量*/typedef struct{ElemType*elem; /* 存储空间基址*/int length; /* 当前长度*/int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */}SqList;#include"bo2-1.c"/* bo2-1.c 顺序表示的线性表(存储结构由c2-1.h定义)的基本操作(12个) */ Status InitList(SqList*L) /* 算法2.3 */{ /* 操作结果:构造一个空的顺序线性表*/(*L).elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!(*L).elem)exit(OVERFLOW); /* 存储分配失败*/(*L).length=0; /* 空表长度为0 */(*L).listsize=LIST_INIT_SIZE; /* 初始存储容量*/return OK;}Status DestroyList(SqList*L){ /* 初始条件:顺序线性表L已存在。
第1页 标准模板库(STL)介绍
作者:Scott Field
本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到函数对象,而且例子丰富,通俗易懂。
0 前言 1 定义一个list 2 使用list的成员函数push_back和push_front插入一个元素到list中 3 list的成员函数empty() 4 用for循环来处理list中的元素 5 用STL的通用算法for_each来处理list中的元素 6 用STL的通用算法count_if()来统计list中的元素个数 7 使用count_if()的一个更加复杂的函数对象。 8 使用STL通用算法find()在list中查找对象 9 使用STL通用算法find_if()在list中搜索对象 10 使用STL通用算法search在list中找一个序列 11 使用list的成员函数sort()排序一个list。 12 用list的成员函数插入元素到list中 13 List 构造函数 14 使用list成员函数从list中删除元素 15 用list成员函数remove()从list中删除元素。 16 使用STL通用算法remove()从list中删除元素 17 使用STL通用算法stable_partition()和list成员函数splice()来划分一个list 18 结论 在field中使用STL 19 参考书目
第2页
0 前言
这篇文章是关于C++语言的一个新的扩展——标准模板库的(Standard Template Library),也叫STL。
当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话题的深度和广度。有很多内容要含盖,也有很多详细描述STL的书。因此我重新考虑了一下我原来的想法。我为什么要写这篇文章,又为什么要投稿呢?这会有什麽用呢?有再来一篇关于STL的文章的必要吗? 当我翻开Musser and Saini的页时,我看到了编程时代在我面前消融。我能看到深夜消失了,目标软件工程出现了。我看到了可维护的代码。一年过去了,我使用STL写的软件仍然很容易维护。让人吃惊的是其他人可以没有我而维护的很好! 然而,我也记得在一开始的时候很难弄懂那些技术术语。一次,我买了Musser&Saini,每件事都依次出现,但是在那以前我最渴望得到的东西是一些好的例子。 当我开始的时候,作为C++一部分的Stroustrup还没出来,它覆盖了STL。 因此我想写一篇关于一个STL程序员的真实生活的文章可能会有用。如果我手上有一些好的例子的话,特别是象这样的新题目,我会学的更快。 另外一件事是STL应该很好用。因此,理论上说,我们应该可以马上开始使用STL。 什麽是STL呢?STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。 STL的目的是标准化组件,这样你就不用重新开发它们了。你可以仅仅使用这些现成的组件。STL现在是C++的一部分,因此不用额外安装什麽。它被内建在你的编译器之内。因为STL的list是一个简单的容器,所以我打算从它开始介绍STL如何使用。如果你懂得了这个概念,其他的就都没有问题了。另外,list容器是相当简单的,我们会看到这一点。 这篇文章中我们将会看到如何定义和初始化一个list,计算它的元素的数量,从一个list里查找元素,删除元素,和一些其他的操作。要作到这些,我们将会讨论两个不同的算法,STL通用算法都是可以操作不止一个容器的,而list的成员函数是list容器专有的操作。
这是三类主要的STL组件的简明纲要。STL容器可以保存对象,内建对象和类对象。它们会安全的保存对象,并定义我们能够操作的这个对象的接口。放在蛋架上的鸡蛋不会滚到桌上。它们很安全。因此,在STL容器中的对象也很安全。我知道这个比喻听起来很老土,但是它很正确。 STL算法是标准算法,我们可以把它们应用在那些容器中的对象上。这些算法都有很著名的执行特性。它们可以给对象排序,删除它们,给它们记数,比较,找出特殊的对象,把它们合并到另一个容器中,以及执行其他有用的操作。 STL iterator就象是容器中指向对象的指针。STL的算法使用iterator在容器上进行操作。Iterator设置算法的边界,容器的长度,和其他一些事情。举个例子,有些iterator仅让算法读元素,有一些让算法写元素,有一些则两者都行。 Iterator也决定在容器中处理的方向。 第3页
你可以通过调用容器的成员函数begin()来得到一个指向一个容器起始位置的iterator。你可以调用一个容器的 end() 函数来得到过去的最后一个值(就是处理停在那的那个值)。 这就是STL所有的东西,容器、算法、和允许算法工作在容器中的元素上的iterator。算法以合适、标准的方法操作对象,并可通过iterator得到容器精确的长度。一旦做了这些,它们就在也不会“跑出边界”。还有一些其他的对这些核心组件类型有功能性增强的组件,例如函数对象。我们将会看到有关这些的例子,现在 ,我们先来看一看STL的list。 --------------------------------------------------------------------------------
1 定义一个list
我们可以象这样来定义一个STL的list: #include #include int main (void) { list Milkshakes; return 0; } 这就行了,你已经定义了一个list。简单吗?list Milkshakes这句是你声明了list模板类的一个实例,然后就是实例化这个类的一个对象。但是我们别急着做这
个。在这一步其实你只需要知道你定义了 一个字符串的list。你需要包含提供STL list类的头文件。我用gcc 2.7.2在我的Linux上编译这个测试程序,例如:
g++ test1.cpp -o test1
注意iostream.h这个头文件已经被STL的头文件放弃了。这就是为什么这个例子中没有它的原因。
现在我们有了一个list,我们可以看实使用它来装东西了。我们将把一个字符串加到这个list里。有一个非常 重要的东西叫做list的值类型。值类型就是list中的对象的类型。在这个例子中,这个list的值类型就是字符串,string , 这是因为这个list用来放字符串。
--------------------------------------------------------------------------------
第4页
2 使用list的成员函数push_back和push_front插入一个元素到list中
#include #include
int main (void) { list Milkshakes; Milkshakes.push_back("Chocolate"); Milkshakes.push_back("Strawberry"); Milkshakes.push_front("Lime"); Milkshakes.push_front("Vanilla"); return 0; } 我们现在有个4个字符串在list中。list的成员函数push_back()把一个对象放到一个list的后面,而 push_front()把对象放到前面。我通常把一些错误信息push_back()到一个list中去,然后push_front()一个标题到list中, 这样它就会在这个错误消息以前打印它
了。
--------------------------------------------------------------------------------
3 list的成员函数empty()
知道一个list是否为空很重要。如果list为空,empty()这个成员函数返回真。 我通常会这样使用它。通篇程序我都用push_back()来把错误消息放到list中去。然后,通过调用empty() 我就可以说出这个程序是否报告了错误。如果我定义了一个list来放信息,一个
放警告,一个放严重错误, 我就可以通过使用empty()轻易的说出到底有那种类型的错误发生了。
我可以整理这些list,然后在打印它们之前,用标题来整理它们,或者把它们排序成类。
/* || Using a list to track and report program messages and status */ #include #include #include