求整数1-N范围和为N的所有组合

看到的一道题,给出答案 问题:找出整数1~N范围和为N的所有集合,集合里的数不允许重复。 解答:递归吧 代码如下: #include "stdafx.h" #include <iostream> using namespace std; void PrintResult(int *log,int index) { for (int i = 0; i <index; ++i) { cout<<log[i]<<" "; } cout<<endl; } void CalCombination(int* log,int startNum,int N,int &index) { if (N==0) { PrintResult(log,index); } else { for (int i = startNum; i <= N; ++i) { log[index++]=i; CalCombination(log,i+1,N-i,index); } } index--; } int _tmain(int argc, _TCHAR* argv[]) { cout<<"请输入N:"; int N=20; cin>>N; int *log=new int[N]; int index=0; CalCombination(log,1,N,index); } 要是允许重复,也简单,将递归中的这句话改为: CalCombination(log,i,N-i,index); 同理,还可以解决类似给定一个数组,让求和为N的元素组合,只需要现将元素排个序,然后思路相同。

2013-05-27 · 1 min · bystander

[译]反射(Reflection)和动态(dynamic)

反射 当我们需要检查,调用一个程序集的内容的时候,用反射,比如,当VS给智能提示的时候,就应用了反射。 简单用法实例: var myAssembly = Assembly.LoadFile(@"C:\ClassLibrary1.dll"); var myType = myAssembly.GetType("ClassLibrary1.Class1"); dynamic objMyClass = Activator.CreateInstance(myType); // 获取类的类型信息 Type parameterType = objMyClass.GetType(); // 浏览方法 foreach (MemberInfo objMemberInfo in parameterType.GetMembers()) {Console.WriteLine(objMemberInfo.Name);} // 浏览属性. foreach (PropertyInfo objPropertyInfo in parameterType.GetProperties()) {Console.WriteLine(objPropertyInfo.Name);} //开始调用 parameterType.InvokeMember(“Display”,BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance,null, objMyClass, null); 实际一点的用处呢: 1.当你也要开发一个类似VS的编辑器的时候,要提供智能提示就需要反射 2.当创建单元测试框架的时候,为了测试需要动态调用方法和属性的时候 3.有时候我们想把类型的属性,方法等全部导出的时候 动态dynamic 编程语言分为强/弱类型,dynamic是弱类型,此关键字会让编译器不做编译时的类型检查,只做运行时的检查。 简单用法示例: dynamic x = "c#"; x++; 所以上面这行代码可以编译通过,但会产生运行时一场。 实际用处: 最多的就是通过互操作来操作Office组件的时候了 没有dynamic的时候 / Before the introduction of dynamic. Application excelApplication = new Application(); ((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name"; Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1]; 有了dynamic之后世界就不一样了 dynamic excelApp = new Application(); excelApp.Cells[1, 1].Value = "Name"; Excel.Range range2010 = excelApp.Cells[1, 1]; 两者的区别和联系呢 1.当我们想要在运行时操作一个对象的时候,就会用到这两个 2.反射可以用来检测对象的元数据,也能在运行时调用对象的方法和属性 3.dynamic是.net 4.0新出的关键字,知道方法被调用的时候,编译器才会晓得这个方法到底有还是没有。 4.dynamic内部是使用反射来实现的,它缓存了方法调用来提高性能 5.反射可以调用公有和私有成员,而dynamic智能调用用公有成员 6.dynamic是实例相关的,无法访问静态成员,这种情况下使用反射吧。 **Reflection** **Dynamic** **Inspect (meta-data) ** Yes No **Invoke public members** Yes Yes **Invoke private members** Yes No **Caching** No Yes **Static class ** Yes No 再来一张图... [![](/images/d0e1ec824f1199a847d9a16237673a4a299e0dce.jpg)](http://leaverimage.b0.upaiyun.com/36512_o.jpg) 译自:[http://www.codeproject.com/Articles/593881/What-is-the-difference-between?utm_source=feedly](http://www.codeproject.com/Articles/593881/What-is-the-difference-between?utm_source=feedly)

2013-05-27 · 1 min · bystander

武汉大学论文参考文献格式生成工具(C#)

每次写论文报告什么的,最头疼的就是参考文献的,本来打算写一个论文格式生成工具的,不过,一想起代码量,就有点吓人,所以分而治之,先写参考文献生成工具. 本工具生成的文献格式符合武汉大学本科生论文的格式要求,因此,放心使用,填写内容都是必填,页码什么的要是不知道就随便填一个..你懂的..有问题请留言反馈。 程序提供8种参考文献类型,第9种电子文献,没有实现,因为感觉在论文中参考文献要是网址的话很难看.而且用的不多..其实主要还是懒..每种文献类型需要填写的信息都不一样,8种…8种… 使用方法: 1.在界面右侧选择参考文献类型,然后填写。添加,左侧将会出现 2.如果填写错误,双击左侧条目,即可删除 3.完成后导出,即可在本目录生成docx文档 下载地址:武汉大学论文参考文献格式生成工具

2013-05-24 · 1 min · bystander

引用和指针(C++)

今天在整理收藏夹的时候,又看到了这两篇非常不错的文章,关于指针和引用的,我就不翻译了,文章很简单,不过把其中我觉得很有意思的两部分结合我的理解希望说的更清楚,假定你读这篇文章之前已经知道指针,但是不是很清楚其中的部分。 首先是关于指针的一个直观的一个认识. #include <iostream> int main() { using namespace std; // 声明并初始化指针. unsigned short int * pPointer = 0; // 定义一个unsigned short int 变量 值为35698 unsigned short int twoInt = 35698; // 定义一个unsigned short int 变量 值为 77 unsigned short int oneInt = 77; // 使用&操作符将twoInt的地址赋给指针 pPointer = &twoInt; // pPointer 现在的值就是twoInt的地址了 // 打印 cout << "pPointer的内存地址:\t\t" << &pPointer << endl; cout << "oneInt的内存地址:\t" << &oneInt << "\t整数值:\t" << oneInt << endl; cout << "twoInt的内存地址:\t" << &twoInt << "\t整数值:\t" << twoInt << endl; cout << "pPointer所指向的地址(也就是pPoint的值):\t" << pPointer << "\t整数值:\t" << *pPointer << endl; return 0; } 上面这段代码,声明了一个指针,和两个整数,指针指向第一个整数,然后输出结果(每个人的输出结果不一样)是: pPointer的内存地址: 0xbff43314 oneInt的内存地址: 0xbff43318 整数值: 77 twoInt的内存地址: 0xbff4331a 整数值: 35698 pPointer所指向的地址(也就是pPoint的值): 0xbff4331a 整数值: 35698 这张图是这几个变量的内存分布图,上面一排是内存地址编号,正对我们的是该处的值 指针pPointer这个变量从最左边0xbff43314这个内存位置开始,占用了四个字节,这个一个指针占四个字节,大家都知道的,这个变量的值是一个地址,也就是他的指向地址。 pPointer 所指向的地址呢,是一个short int 类型的值所在的位置,在这里就是我们的twoint,twoint在内存中呢,是从0xbff4331a开始的,也就是说,我们的pPointer指向了twoint所在的地址, 注意,看一下左边四个方块前面的二进制数,转换成16进制就是0xbff4331a了 因此,取指针所指向的值就是35698了。指针本身的值则是0xbff4331a,指针所在的位置是0xbff43314。 参考文章:C++ : Understanding pointers 另一个呢是关于引用的实现原理 大家都知道,引用就是别名,比如下面这段代码 #include <iostream> using namespace std; int main() { int number = 88; // 定义一个int变量 int & refNumber = number; // 声明并初始化一个引用 // 现在他们都表示了同一个值 cout << number << endl; // 打印number的值 (88) cout << refNumber << endl; // 打印引用的值 (88) refNumber = 99; // 给refNumber重新赋一个值 cout << refNumber << endl; cout << number << endl; // number的值也就变成了 (99) number = 55; // 重新给number赋一个值 cout << number << endl; cout << refNumber << endl; // refNumber也就变成了(55) } 输出结果肯定一目了然,其中的原理想过没 ...

2013-05-22 · 1 min · bystander

倒水问题求解(C++)

明天要去参加微软面试,不求顺利,但求体验。 这个题目答题的意思是: 给你一个容量为A升的桶和一个容量为B升的桶,水不限使用,要求精确得到Q升水.请说明步骤 当数字比较小的时候,我们可以通过大脑穷举来得到结果,但这里有两个问题,当数字很大的时候怎么解?题目给定的数据是否有解? 首先判断是否有解? 题目可以理解为,x为用A的次数,y为用B的次数,Q为目标值 Q = A * x + B * y Q =目标值. Q必须是 Gcd(A,B)(也就是A,B的最大公约数)的倍数,否则无解,如果 Gcd(A,B) == 1, 任何Q都是可解的 最简单的方法就是把A的水不断的向B中倒(B向A中倒也行),知道得到最终结果,如果桶满了,就清空该桶.举个例子 A = 3, B = 4 并且 Q = 2 重复得从 A->B A B 0 0 4 0 1 3 1 0 0 1 4 1 2 3 <-A桶中得到2了 试试从 B->A A B 0 0 0 3 3 0 3 3 4 2 <- B中也得到了2 但是注意,从 B->A 比从 A->B快哦 然后我贴出代码 #include "stdafx.h" #include <iostream> #include <vector> #include<string> using namespace std; //热门智力题 - 打水问题 //基本思想:用A桶容量的倍数对B桶的容量进行取余。 //指导方针:不断用A桶装水倒入B桶,B桶满了立即清空 //每次判断下二个桶中水的容量是否等于指定容量。 const string OPERATOR_NAME[7] = { "装满A桶", "装满B桶", "将A桶清空", "将B桶清空", "A桶中水倒入B桶", "B桶中水倒入A桶", "成功得到结果" }; int max(int a,int b) { return a>b?a:b; } int gcd(int m,int n) { int temp,p,r; //n存放最小数,m存放最大数 if(n>m){ temp = n; n = m; m = temp; } p=n*m;//先取得两个数的积 while(n!=0){ r=m%n; m=n; n=r; } return m; } int _tmain(int argc, _TCHAR* argv[]) { int a_capacity, b_capacity, goal_capacity; vector<string> record; //记录操作过程 int a_water, b_water; cout<<"请输入A桶容量,B桶容量,目标容量Q:"; cin>>a_capacity>>b_capacity>>goal_capacity; a_water = b_water = 0; //A桶,B桶中有多少升水 //判断是否一定可解 if (a_capacity<=0 || b_capacity<=0 || goal_capacity<=0) { cout<<"请保证所以容量大于0"<<endl; return -1; } if (goal_capacity>max(a_capacity,b_capacity)) { cout<<"要量出的容量应该小于其中桶容量"<<endl; return -2; } //如果可解则解之 if(goal_capacity%gcd(a_capacity,b_capacity)==0) { //存放临时的字符串构造 char szTemp[30]; while (true) { if (a_water == 0)//A桶没水,就装满水 { a_water = a_capacity; sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[0] + szTemp);//先填满 A桶 } else { //如果A桶的水比(B桶容量-B桶的水)要多,也就是多于没装满的B桶空出来的部分,A桶会剩下 if (a_water > b_capacity - b_water) { //A桶向B桶倒水直到B桶满,此时A桶的水==A桶的水+B桶的水-B桶容量 a_water = a_water + b_water- b_capacity; b_water = b_capacity; //B桶的水装满了 sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[4] + szTemp);//A->B if (a_water == goal_capacity) break; b_water = 0; //将B桶清空 sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[3] + szTemp); } else { //A桶小于装满B桶需要的水,此时B桶的水==A桶的水+B桶的水 b_water += a_water; a_water = 0; sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[4] + szTemp);//A->B if (b_water == goal_capacity) break; } } } record.push_back(OPERATOR_NAME[6]); //break出来说明成功了 cout<<"\n---------------------------------------------------"<<endl; cout<<"以下下是一种方案"<<endl; vector<string>::iterator pos; for (pos = record.begin(); pos != record.end(); pos++) cout<<*pos<<endl; cout<<"---------------------------------------------------"<<endl; } else { cout<<"此情况下无解"<<endl; } return 0; } 运行结果如下: ...

2013-05-15 · 2 min · bystander

[藏]社交网络,电子时代的人生绑架者

作者:负二 bystander:本文回答了你刷社交网络的内在因素.希望读到的人不只是读到那么简单. 大家在互相打招呼之前,先各自拿出手机,其中几个人用手机“签到”,然后把“签到”信息转发给在场的每一个人,而另一些人则用手机给饭桌上的菜肴拍照,然后同样转发给在场的每一个人,直到各种提示音消失之后,大家开始一边动筷子,一边心不在焉地聊八卦,如果没有爆炸性的话题出现,吸引在场的每一个人的注意力,那么大家的注意力都会被自己的手机虏获——比如我会收到坐在对面的那人发来的一张用手指画的拙劣的涂鸦,然后让我根据此图猜一个单词。 现在,一次聚餐的情景差不多就是这样,把一盘菜的照片转发给就坐在你身边和你一起吃饭的那个人,这种事说起来真是要多蠢有多蠢,但人们仍是乐此不疲——当一台饮水机都拥有一个微博账号时,我们意识到任何事情都已经无法阻止网络社交了,无论是美食还是同学聚会。 大多数热衷于用手机刷新SNS网站的人并不认为对网络社交上瘾是什么问题——他们有种幻觉:需要的时候,我肯定能够克制自己,那肯定比戒烟容易。但事实并非如此,网络社交上瘾与烟瘾截然不同,如果你对它背后的机制有所了解,一定会对它能够利用人类心理的弱点到如此地步深感惊讶——一个正常人只要掉进这个圈套,就几乎不可能不对这玩意上瘾。 如果你有过在泡论坛时不断刷新页面的经历,你就会明白社交网站的通知系统是一个多么精巧的引人上钩的设计——人们难以容忍等待,他们需要新状态的刺激,现代化的机场都将下飞机口到取行李处的距离设计得要多漫长有多漫长,就是为了避免旅客在取行李处叉着双手等行李,因为“走”比“等”更容易让人接受——而创造通知系统的产品经理们显然深谙此道,只要通知系统不断地给出状态更新的通知,就能够让人每天乖乖地登录,然后长时间地留在你的社交网站上,这一招就像用香肠逗狗一样好用。 许多人认为社交网站降低了人与人之间交流的成本,促进了信息流动和世界大同——他们显然是被Facebook、新浪微薄之类的网站给蒙骗了;而对人类社会的本质有所了解的人则会同意窥私欲是支撑社交网站的动力之一——有一定道理,人们总是有无穷的动力想去瞧瞧多年不见的老朋友、老同学,或是初恋情人,看他们是不是过得比自己更差,我的表弟曾向我坦白,在他听说前女友离婚的消息后,他曾连续一个月关注她的微博和开心网账号,并且觉得很爽——巴菲特说,竞争并不是推动人类前进的动力,嫉妒才是。 但实际上,窥私欲在社交网络这盘大菜中顶多只能算是几滴酱油——如果你对人性有更透彻的认识,你会从“把一盘菜的照片转发给和你一起吃饭的每一个人”这一举动上看到更深层次的动机。只有够自恋的人才会认为“我在吃这盘菜”这件事很重要,重要到有必要让每个人知道的地步——不幸的是,这世界上除了抑郁症患者,每个人都够自恋,你只要稍加注意就会发现,社交网络中的大多数信息都与“交流”没半毛钱关系,只是某人发布的“自以为很重要”的自我推销信息而已。根据“人类自我表现理论”,人们的自我表现往往根据相互关系中对方的特点而采取某种相应的对策,人们会不断地调节和控制呈现给其他人的信息,特别是有关自我的信息,以便建立起有利于自己的形象——所以人们会狂热地维护自己的微博形象,对隐私泄露视而不见,而对爱你的家人恶言相向。 最新的研究表明,热衷社交网络,也很有可能是你不够成功的表现——美国人4个中有3个是Facebook用户,但在可支配财产超过100万美元的人群中,这一比例只有26%,而百万富翁中上Twitter的比例更是只有可怜的3%——心理学家指出,原因可能是财富给予人更多的独立意识,对他人的依赖越少,对他人就越少在意,产生自我关注的倾向。想必扎克伯格自己也不会一天到晚泡在自己的网站上——而这世界上大多数人都“不够成功”,毫无疑问。 只要看透这一切,你就会明白,社交网络热潮,根本不是什么科技革命,它只不过是人性弱点的一次集中爆发而已,并且在它不为人所见的屁股后面,多多少少都能闻出一丝阴谋家的味道——自由软件基金会主席Richard Stallman认为,基于实名制的Facebook是一个国际寄生项目,而Jonathan Nolan(《盗梦空间》编剧)则在他的新剧中直接说,Facebook的幕后金主其实是CIA,自从全世界的人们都那么乐意泄露隐私后,CIA的工作简单了不少。 现在看来,远离通知提示音的诱惑,从社交网络那里为自己“赎身”,才是人生正途。

2013-05-13 · 1 min · bystander

[已失效]Csdn免积分下载器

作者:bystander 转载请注明来源:http://leaver.me 原理很简单,目前好像还没有大规模传开,我就不透露了,大家低调使用.为了方便,我写了个客户端,下载地址在文章末尾 使用方法直接把你想下载的地址复制过去,点击下载就会调用ie来下载了. 文章太短了,发两个可乐的吧: 第一个是: "网上发言,请不要随便自称笔者,毕竟有没有在用笔在写一目了然。这个词汇已经要汇入历史长河了,虽然曾经的那么疯狂存在过,但至少在互联网上该消失了。" "那以后自称什么?" "键人。" ---------------------------------------------------------------------------------------------------------- 第二个: ---光棍君:五一快到了,你还是一个人吗? ---你MB,难道我会变成狗吗? ---------------------------------------------------------------------------------------------------------- 第一个冷笑话,第二个是热笑话,冷暖自知。一个成语瞬间提升了整篇文章的境界。 下载地址:[Csdn下载器](http://pan.baidu.com/share/link?shareid=468747&uk=1493685990)

2013-05-01 · 1 min · bystander

一道笔试指针题目详解

看到本题是在搜狗某年的笔试题上,看也没人给出非常详细的讲解,直接给出了答案,我来尝试写一写, 貌似本题来源自<**The C Puzzle Book> ,**搜狗也只是换了一下字符串,直接看题吧 #include <stdio.h> char *c[]={"ENTNG", "NST","AMAZI","FIRBE"}; char** cp[]={c+3, c+2, c+1, c}; char ***cpp= cp; int main() { printf("%s",**++cpp); printf("%s ",*--*++cpp+3); printf("%s",*cpp[-2]+3); printf("%s",cpp[-1][-1]+1); } <span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px;">请写出程序的执行结果....</span> 首先从左到右看: char *c[]= { "ENTNG", "NST", "AMAZI", "FIRBE" }; *c[] 是一个字符,因此,c[]是指向该字符,c就是一个数组(数组的内容为指向字符的指针),c已经被初始化了. char** cp[]={c+3, c+2, c+1, c}; 再看第二行,**cp[]是一个字符,*cp[]就是一个指针,指向该字符,cp[]就是一个指针,指向该指针,而cp就成为了指针数组,内容是指向字符的指针的指针。并且通过c的元素进行了初始化 char ***cpp= cp; 第三行,***cpp是一个字符,**cpp指向该字符,*cpp指向该指针,cpp就指向该字符的指针的指针. 然后我画一张图表示初始的情况看看 然后对于下面的输出语句,通过操作符优先级使用括号来区分一下: *(*(++cpp)); 这个嘛,就是把cpp后移(注意cpp已经改变了)然后就指向了cp[1],然后两次取其值即可得到AMAZI 推导过程如下: ++cpp -> cp[1] // cp[1] -> c+2 ++cpp = &cp[1] // &(c+2) *++cpp = *(&c+2) // c[2] **++cpp = *&c[2] 然后看第二个 (*(--(*(++cpp))))+3; 加括号后如上,cpp再加一,就指向了cp[2],取一次值(也就是*号)就变成了c[1],然后--c[1]就指向了c[0],取值就成了c[0]的地址,然后地址+3,就是NG了 (*(cpp[-2]))+3; 上面,cpp指向cp[2]了,然后呢,cpp[-2] 相当于*(cpp-2),间接引用cp[2],这样cpp[-2]就指向了cp[0]了,然后,就是FIRBE了,加3就是BE了 最后 (cpp[-1][-1])+1; cpp还是之前的cp[2],cpp[-1][-1]相当于*(*(cpp-1)-1),先减1指向了cp[1],取一次值就是c[2]了,然后c[2]-1就成为c[1]了,然后+1之后就是ST了. 所以,最后输出就是 AMAZINGBEST 错误之处还望指正.

2013-04-17 · 1 min · bystander

模板优先级队列及堆排序(C++实现)

模板优先级队列,数组实现,再熟悉一下常用算法,同时简单的堆排序应用 写了一个是队列自增长,另一个为了演示我还添加了一个叫做FillPq的方法,这个方法可以使用一个数组直接填充到优先级队列里,此时,优先级队列并不优先,然后进行下滤调整,之后建堆完成,输出即可 #include "stdafx.h" template< class T> class PriorityQueue { private: T *pq; int N; int capacity; public: PriorityQueue(void); ~PriorityQueue(void); void Insert(T x); T DelTop(); void Swim(int k); void Sink(int k); bool Less(int i,int j); void Swap(int i,int j); bool Resize(); void FillPq(T arr[],int size); }; template< class T> void PriorityQueue<T>::FillPq( T arr[],int size ) { N=size; capacity=2*size; for (int i=0;i<size;i++) { pq[i+1]=arr[i]; } } template< class T> PriorityQueue<T>::PriorityQueue(void) { pq=new T[10]; N=0; capacity=10; } template< class T> void PriorityQueue<T>::Insert( T x ) { if (N==capacity) { Resize(); } pq[++N]=x; Swim(N); } template< class T> T PriorityQueue<T>::DelTop() { T max=pq[1]; Swap(1,N--); Sink(1); pq[N+1]=NULL; return max; } //下滤 template< class T> void PriorityQueue<T>::Sink( int k ) { while (2*k<=N) { int j=2*k; if (j<N && Less(j,j+1)) { j++; } if (!Less(k,j)) { break; } Swap(k,j); k=j; } } //上浮 template< class T> void PriorityQueue<T>::Swim( int k ) { while (k>1 && Less(k/2,k)) { Swap(k,k/2); } } template< class T> void PriorityQueue<T>::Swap( int i,int j ) { T temp=pq[i]; pq[i]=pq[j]; pq[j]=temp; } template< class T> bool PriorityQueue<T>::Less( int i,int j ) { return pq[i]<pq[j]; } template< class T> bool PriorityQueue<T>::Resize() { T *newPq=new T[capacity*2]; capacity=capacity*2; for (int i=1;i<=N;i++) { newPq[i]=pq[i]; } pq=newPq; return true; } template< class T> PriorityQueue<T>::~PriorityQueue(void) { } 然后是堆排序 ...

2013-04-16 · 2 min · bystander

模板栈以及中缀表达式求值(C++实现)

栈直接用链表实现,这个比较简单,不多说,不过C++写程序,IDE的错误检测不是很给力。 至于给定一个中缀表达式,如何不转换成后缀表达式,直接求值,方法就是使用两个栈,一个操作符栈,一个操作数栈,然后从左到右扫描表达式,我这里中缀表达式计算实现的很简单,不完整,大家可以扩展。栈的实现是我想写的,思路如下: 1.如何是操作数,压入操作数栈 2.如果是操作符,压入操作符栈 3.如果是左括号,直接忽略 4.如果是有括号,弹出操作符栈栈顶元素,然后弹出操作数栈两个元素,进行操作以后结果压入操作数栈 看个图就好了 最后给出栈顶实现代码 #include "stdafx.h" #pragma region Node定义 template <class T> class Node { template<class T> friend class Stack; private: T m_data; Node *pNextNode; public: Node(); Node(T d); }; template <class T> Node<T>::Node() { m_data=default(T); pNextNode=NULL; } template <class T> Node<T>::Node(T d) { m_data=d; pNextNode=NULL; } #pragma endregion #pragma region Stack定义 template <class T> class Stack { private: Node<T> *m_pTopNode; int m_nNodeCount; public: Stack(); ~Stack(); bool IsEmpty(); bool Push(T e); T Pop(); int Size(); }; template <class T> Stack<T>::Stack() : m_pTopNode(NULL),m_nNodeCount(0) { } template <class T> Stack<T>::~Stack() { while (!IsEmpty()) { Node<T> *pTempNode = m_pTopNode; m_pTopNode = m_pTopNode->pNextNode; delete (pTempNode); pTempNode = NULL; } m_nNodeCount = 0; m_pTopNode = NULL; } template <class T> bool Stack<T>::IsEmpty() { return (m_pTopNode == NULL); } template <class T> bool Stack<T>::Push(T e ) { Node<T> *pNewNode = new Node<T>(e); if (NULL == pNewNode) { return false; } if(! IsEmpty()) { pNewNode->pNextNode = m_pTopNode; } m_pTopNode = pNewNode; m_nNodeCount ++; return true; } template <class T> T Stack<T>::Pop() { if(IsEmpty()) { return T(-1); } T e; e = m_pTopNode->m_data; Node<T> *pNode = m_pTopNode; m_pTopNode = m_pTopNode->pNextNode; delete (pNode); m_nNodeCount--; return e; } template <class T> int Stack<T>::Size() { return m_nNodeCount; } #pragma endregion 然后是main函数代码 ...

2013-04-11 · 2 min · bystander