九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

关于容器输出的学习与简化过程

在学习C++标准库的过程中,各种容器是很大一块,每次验证自己的结果输出容器的时候除了string 可以简单的cout<<输出以外,其他的都要for()循环用迭代器遍历,比如输出vector<int> vec容器就要这样

for(vector<int>::iterator it = vec.begin(); it != vec.end(),++it)

    cout<<*it<<" :;

cout<<endl;

很不方便,所以以前就自己编了个重载函数printCon以输出常用的容器

void printCon(list<int>::const_iterator,list<int>::const_iterator);
void printCon(deque<int>::const_iterator,deque<int>::const_iterator);
void printCon(vector<int>::const_iterator,vector<int>::const_iterator);
void printCon(vector<string>::const_iterator,vector<string>::const_iterator);

main()

{return 0;}

void printCon(list<int>::const_iterator first,list<int>::const_iterator last)
{
 cout<<endl;
 for(;first != last;++first)
 {
  cout <<*first<<" ";
 }
 cout<<endl;
}
void printCon(deque<int>::const_iterator first,deque<int>::const_iterator last)
{
 cout<<endl;
 for(;first != last;++first)
 {
  cout <<*first<<" ";
 }
 cout<<endl;
}
void printCon(vector<int>::const_iterator first,vector<int>::const_iterator last)
{
 cout<<endl;
 for(;first != last;++first)
 {
  cout <<*first<<" ";
 }
 cout<<endl;
}
void printCon(vector<string>::const_iterator first,vector<string>::const_iterator last)
{
 cout<<endl;
 for(;first != last;++first)
 {
  cout <<*first<<" ";
 }
 cout<<endl;
}

 

使用起来还算方便,也简洁,只要两个迭代器就可以遍历输出容器,而且输出范围内的容器也可以。就是代码比较复杂,假如要适应全部的容器,代码将会复杂的吓人,但我没有学过模版,不知道那样是不是可以使这个函数简单一些,不过学了流迭代器以后,问题得到了解决,上面那个问题,只需要

std::ostream_iterator<int> ost_iter(cout," "); 
std::copy(vec.begin(),.vec.end(),ost_iter);

就可以得到解决了,真是简单多了啊,终于知道为什么C++要定义输出流迭代器这乍一看没有什么用的东西了。

阅读全文....

关于C++标准库泛型算法reverse的学习笔记

C++ Primer中这样描述reverse 反向排列元素

一个容器为 9,8,7,6,5,4,3,2,1,0,sort后为0,1,2,3,4,5,6,7,8,9。

一个容器为0,1,2,3,4,5,6,7,8,9,sort后还为0,1,2,3,4,5,6,7,8,9。

假设一个容器为0,1,2,3,4,5,6,7,8,9你认为reverse以后为什么呢?没有错,9,8,7,6,5,4,3,2,1,0。

但是一个容器本来就为 9,8,7,6,5,4,3,2,1,0呢?还是9,8,7,6,5,4,3,2,1,0吗?他们不是本来就降序排列了吗?

我以前就是这样理解的,不过实际使用才知道reverse不时排序算法,仅仅是反向排列。9,8,7,6,5,4,3,2,1,0

reverse后变成0,1,2,3,4,5,6,7,8,9。要得到降序排列的方法,好像可以先sort,后reverse.不知道我说的对不对。

具体的验证代码就很简单,不列出来了。 

阅读全文....

关于C++标准库泛型算法merge的学习笔记

#include <vector>
#include <string>
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

int main(int argc, char *argv[])     
{
 std::ostream_iterator<int> ost_iter(cout," ");
 list<int> lst1;
 for(int i = 0;i<10;++i)
  lst1.push_back(i);
 list<int> lst2;
 for(int i = 0;i<10;++i)
  lst2.push_front(i);
 merge(lst1.begin(),lst1.end(),lst2.begin(),lst2.end(),ost_iter);
 cout<<endl;
 return 0;
}

会发现程序编译成功,但是运行出错,原因在于merge算法应用时必须先排序才行,改成下面这样:

。。。省略预编译与using

int main(int argc, char *argv[])     
{
 std::ostream_iterator<int> ost_iter(cout," ");
 list<int> lst1;
 for(int i = 0;i<10;++i)
  lst1.push_back(i);
 list<int> lst2;
 for(int i = 0;i<10;++i)
  lst2.push_front(i);
 std::copy(lst1.begin(),lst1.end(),ost_iter);
 cout<<endl;
 std::copy(lst2.begin(),lst2.end(),ost_iter);
 cout<<endl;
 lst1.sort();
 std::copy(lst1.begin(),lst1.end(),ost_iter);
 cout<<endl;
 lst2.sort();
 std::copy(lst2.begin(),lst2.end(),ost_iter);
 cout<<endl;
 merge(lst1.begin(),lst1.end(),lst2.begin(),lst2.end(),ost_iter);
 cout<<endl;
 return 0;
}

文件成功,但是两个容器0,1,2,3,4,5,6,7,8,9合并,竟然变成0,0,1,1,2,2。。。。。奇怪吧。另外,lst1.sort()可以去掉,因为它已经是排好序的了,换句话说,merge运行正确的前提是排好序,而不是一定要你先运行sort()。另外merge不仅有合并的意思,还有融入的意思,感觉这里更像是融入,而不是简单的合并,即我理解的合并在后面。当然,假如仅仅是加在后面用insert就可以了,没有必要用merge 而且,假如merge像,那样还需要先排序干什么呢?

阅读全文....

保存学习档案的小管理器

做来玩,自己也用。

源代码:http://pickup.mofile.com/7117077873846058

mofile文件提取方法自己看看吧,还比较简单,既然大家学的都是C++这种难东西,mofile这简单的东西,我就不多说了。www.mofile.com  去看看吧

因为源代码比较大,不列出来了,自己看吧,编译工具为visual C++ .net 2005,你也可以更改按钮的内容,以

适用你自己的情况:)注意的是文件保存地址你必须修改,不然不能运行,至于怎么修改就不用我多说了吧,自己看看吧

 

阅读全文....

一个最最简单的画图软件

唯一值得一用的特点是,可以重复你画画时候的先后顺序(也就是轨迹)。

源程序:

读图程序:http://pickup.mofile.com/4033993311440329

画图程序:http://pickup.mofile.com/1221180278844126

 

//先用画图程序画图,画完后直接关闭程序就可以了,再运行读图程序读图。图片文件以txt形式保存。

 //当时写的时候没有想过要贴上来,所以一点注释也没有,而且现在再回去看的时候,发现其实

//读图程序有严重的问题,根本没有画线,只是画点而已,所以当画图程序画快了,就不能很好的还原

//注意,假如你要在你自己的机子上运行程序,请必须改变文件保存的地址

//在vc++.net 2005下编译 

阅读全文....

C++ Primer 中文版 第4版 习题10.2

/*我在这里写下部分C++ Primer 中文版 第4版 习题的个人解答和看法(注:我没有买答案书,所以不保证正确,你觉得错的,希望你能告诉我)源代码运行的要求和书上一样,省略了预编译和using行。假如有什么说的不详细,你还不懂,可以问我,不过我也是初学者,不一定知道阿,看我还在学C++ Prime 就知道我是初学者了。欢迎转载,但是请保留作者名“九天雁翎”。*/

 

typedef pair<string,int> sipair;    //简化定义方法
typedef vector<sipair> sidv;
int main()
{
 string stra;
 int ia;
 sipair paira,pairb;
 sidv sidva;
 while(cin>>stra>>ia)
 {
  paira.first = stra;
  paira.second = ia;    //第一种方法
  pairb = make_pair(stra,ia);  //第二种方法
  sipair pairc(paira);           
  sipair paird(stra,ia);          //不知道上面这两种算不算,原题要求3种
//我认为这几种方式的理解都还好,只是使用上的简单有点差别 
  sidva.push_back(paira);
 }
 for(sidv::iterator it = sidva.begin();it != sidva.end();++it)
 {
  cout<<"the pair is:"
   <<it->first<<" "<<it->second<<endl;
 }
 
 return 0;
}

 

阅读全文....