C++基础笔记(三)

32、STL(Standard Template Library)是一个基于模板的容器类库,包括向量、链表、队列及一些通用的排序和查找算法等。
33、转义字符以"\"引导,如“\\”表示“\”等。  
34、在一个类定义的内部定义一个类,称为嵌套类。嵌套类的成员函数和静态成员可以在包含该类的外部定义,但嵌套灰的作用域在包含该类定义的内部。  
35、使用异常

异常枚举族系

1)enum FileErrors{nonExist,wrongFormat,diskSeekError};

2)int f()

3){

4)try

5)  {

6)   //...

7)  }//try

8)catch(FileErrors fe)

9)  {

10)  switch(fe)

11)  {

12)  case nonExist:

13)   //...

14)  case wrongFormat:

15)   //...

16)   ...

17)  }//switch

18)  }//catch

19)}//if

异常派生层次结构

class FileErrors();

class NonExist:public FileErrors{};

class WrongFormat:public FileErrors{};

//...

int f()

{

try

  {

  //...

  throw WrongFormat;

  }

catch(NonExist)

  {

  //...

  }

//...

catch(FileErrors) 

  {

  //...

  }

}//f   

注意:

异常处理的数据类型可以是公有基类或指向公有基类的指针,抛弃异常的数据类型可是派生类或指向派生类的指针。

因为“catch(基类)”总能够捕获“throw 派生类对象”,所以“catch(基类)”块总是放在“catch(派生类)”块的后面,以避免“catch(派生类)”永远不能捕获异常。                 

一、一个问题的几种解决方法

1、Josephus问题:一群小孩围成一圈,任意假定一个数m,从第一个小孩起,顺时针方向数,每数到m个小孩时该小孩便离开。小孩不也不离开,围子不断缩小。最后剩下的一个小孩便是胜利者,问是那个小孩?

用面向过程思想来解决之:

     本问题与小孩的规模和假定的数m有关。解决方法如下,我们采用数组。

#include <iostream>

using namespace std;

int main()

{

int num=10;

int a[num];

for(int i=0;i<num;i++)

 a[i]=i+1;

cout<<"input the interval:\n";

int interval;

cin>>interval;

int k=1;

int i=-1;

while(1)

{

  for(int j=0;j<interval;)

   {

    i=(i+1)%num;

 if(a[i]!=0)

  j++;

   }//for

  if(k==num) break;

  cout<<a[i]<<" ";

  a[i]=0;

  k++;

}//while

//break跳转到此

cout<<"\nNo."<<a[i]<<"boy've won.\n"; 

return 1;

}

我们采用结构链表方式如下处理:

#include <iostream>

#include <iomanip>

using namespace std;

struct jose

{

int code;

jose* next;

};

int main()

{

int num,interval;

cout<<"input num of boys:\n";

cin>>num;

cout<<"input interval:\n";

cin>>interval;

jose* pJose=new jose;

jose* pCurrent=pJose;

int item=0;

int i;

for(i=1;i<num;i++)

  {

   jose* temp=new jose; 

   pCurrent->next=temp;

   pCurrent->code=i;

   pCurrent=pCurrent->next;

   if(item++ % 10==0) cout<<endl;

   cout<<setw(4)<<i;

  }//for

pCurrent->next=pJose;

pCurrent->code=num;

cout<<setw(4)<<i;

//*******以上过程为生成带有编号的小孩的一个圈

cout<<"\nfrom which boy to start?\n";

int tmp;

cin>>tmp;

jose* tempp=pJose;

for(;tempp->code!=tmp;tempp=tempp->next) ;

//*********找到开始的小孩

pCurrent=tempp;

jose* pivot;

item=0;

while(pCurrent->next!=pCurrent)

  {

  for(int j=0;j<interval;j++)

    {

    pivot=pCurrent;

 pCurrent=pivot->next;

    }//for

  if(item++ % 10==0) cout<<endl;

  cout<<setw(4)<<pCurrent->code;

  pivot->next=pCurrent->next;

  delete pCurrent;

  pCurrent=pivot;

  }//while

cout<<"\nthe winner is: "<<pCurrent->code<<endl;

delete pCurrent;

return 1;

}

用面向对象思想来解决之:

       我们用最直观的思路去思考。只需要从外界得知共有内个小孩,从那个小孩子开始,及数几个小孩这些数据就可以得出结果来。

       所以我们先构造一个类,来描述上述特征,它具有得知上述几个数据后,便可求求获胜者的功能。如下所描述:

josex.h

class Jose

{

public:

 Jose(int boys=10,int begin=1,int m=3)

 {

 numOfBoys=boys;

 beginPos=begin;

 interval=m;

 }//Jose

 void Initial();

 void GetWinner();

protected:

 int numOfBoys;

 int beginPos;

 int interval;

};

我们采用链表结构来处理孩子间的关系,所以在具体到求获胜者的过程中,需要涉及到对链表的删除插入输出数小孩子等操作,我们将之定义到另外一个类中。如下:

ring.h

struct Boy

{

int code;

Boy* next;

};

class Ring

{

public:

 Ring(int n);

 void Count(int m);//数m个小孩

 void PutBoy();   //输出当前小孩的编号

 void ClearBoy(); //删除当前小孩子

    ~Ring();

protected:

 Boy* pBegin;

 Boy* pivot;

 Boy* pCurrent;

};

完整程序如下所示:

Jose.cpp

#include <iostream>

#include "ring.h"

#include "josex.h"

using namespace std;

void Jose::Initial()

{

int num,begin,m;

cout<<"input num and begin,m(interval):\n"<<endl;

cin>>num>>begin>>m;

//我们在这里假设输入的数据都是正确的,不在检验

numOfBoys=num;

beginPos=begin;

interval=m;

}//Initial

void Jose::GetWinner()

{

Ring x(numOfBoys);

x.Count(beginPos); //转到开始位置

for(int i=1;i<numOfBoys;i++)

  {

   x.Count(interval);

   x.PutBoy();

   x.ClearBoy();

  }//for

cout<<"\nthe winner is: ";

x.PutBoy();

}//GetWinner

Ring.cpp

#include <iostream>

#include <iomanip>

#include "ring.h"

using namespace std;

Ring::Ring(int n)

{

pBegin=new Boy[n];

pCurrent=pBegin;

for(int i=1;i<=n;i++,pCurrent=pCurrent->next)

  {

   pCurrent->next=pBegin+i%n;

   pCurrent->code=i;

   PutBoy();

  }//for

cout<<endl;

pCurrent=&pBegin[n-1];//当前小孩位置在最后一个编号

}//Ring

void Ring::Count(int m)

{

for(int i=0;i<m;i++)

  {

  pivot=pCurrent;

  pCurrent=pivot->next;

  }//for

}//Count

void Ring::PutBoy()

{

static int numInLine;

if(numInLine++%10==0)

 cout<<endl;

cout<<setw(4)<<pCurrent->code;

}//PutBoy

void Ring::ClearBoy()

{

pivot->next=pCurrent->next;

pCurrent=pivot;

}//ClearBoy

Ring::~Ring()

{

delete[] pBegin;

}//~Ring

Main.cpp

#include "josex.h"

int main()

{

Jose jose;

jose.Initial();

jose.GetWinner();

return 1;

}

说明:阅读钱老师书笔记。

发布了208 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hopegrace/article/details/104219358