?? josep.cpp
字號:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class List;
class OutOfBounds{};
class Node//節(jié)點類
{
friend class List;
friend bool Jose(const int& total,const int& distance,const int& par,
int* survivor_num,int* survivor_list);
private:
int data; //用于存儲每個人在圈中的序號
string name; //存儲每個人的名字
Node* next;
};
class List
{
public:
List();
~List();
//輸入表中人的序號,得到其名字存儲在name中
bool Retrieve(const int num,string& name) const;
//在指定的位置k處插入節(jié)點
List& push_back(const int& x,const string& name);
//刪除指定的節(jié)點
List& Delete(Node* current);
friend bool Jose(const int& total,const int& distance,const int& par,
int* survivor_num,int* survivor_list);
private:
int len;//表的長度
Node* last;//指向最后一個節(jié)點的指針
};
List::List()//默認表中沒有元素
{
last=NULL;
len=0;
}
List::~List()//析構(gòu)函數(shù),刪除節(jié)點
{
Node* next;
while(len-->1)
{
next=last->next;
delete last;
last=next;
}
delete last;
}
//輸入表中人的序號,得到其名字存儲在name中
bool List::Retrieve(const int num,string& name) const
{
Node* current=last->next;
int index=0;
while(index++<len)
{
if(current->data==num)
{
name=current->name;
return true;
}
current=current->next;
}
return false;
}
//刪除p指向的節(jié)點
List& List::Delete(Node* p)
{
Node* current=last->next;
Node* c=last;
int index=0;
while(index++<len)
{
if(current==p)
{
c->next=current->next;
if(current==last) last=c;
delete p;
len--;
return *this;
}
else
{
c=current;
current=current->next;
}
}
if(index==len) throw OutOfBounds();//p指向的節(jié)點不在該鏈表中,拋出異常
return *this;
}
//在鏈表的末尾插入一個元素
List& List::push_back(const int& num,const string& name)
{
Node* p=new Node;//新建一個節(jié)點
p->data=num;
p->name=name;
if(last)
{
Node* temp=last->next;
last->next=p;
p->next=temp;
last=p;
}
else
{
last=p;
p->next=p;
}
len++;
return *this;
}
bool Jose(const int& total,const int& distance,const int& par,
int* survivor_num,int* survivor_list)
{
List list;
for(int i=0;i<total;i++)
{
list.push_back(i+1,"");
}
Node* current=list.last->next;
int j=0;
for(; j<total-par ;j++)
{
int k=distance%list.len;
if(!k) k=list.len;
for(;k>1;k--)
{
current=current->next;
}
survivor_list[j]=current->data;
Node* c=current;
current=current->next;
list.Delete(c);
}
for(int m=0;m<par;m++)
{
for(int n=0;n<total-par;n++)
{
if(survivor_num[m]==survivor_list[n]) return false;
}
}
return true;//最后的par個數(shù)與文件中讀入的序列相同,表明該distance 滿足要求,返回true
}
int Josep(int total,int par,int* survivor_num,int* survivor_list)
{
for(int distance=1; ;distance++)
{
if(Jose(total,distance,par,survivor_num,survivor_list))
return distance;
}
}
void main()
{
ifstream Input("input.txt");
if(!Input)
{
cerr<<"Fail to open the \"input.txt\"!"<<endl;
exit(1);
}
cout<<"Suceed to open the \"input.txt!\""<<endl;
ofstream Output("output.txt");
if(!Output)
{
cerr<<"Fail to open or built the \"output.txt\"!"<<endl;
exit(1);
}
cout<<"Suceed to open the \"output.txt\"!"<<endl;
int total,par;
Input>>total>>par;//從文件中讀入總?cè)藬?shù)和排在最后的指定的人數(shù)
if(par<1 || total<1) //檢測輸入是否合法
{
cout<<"Wrong input!Please check it!"<<endl;
throw OutOfBounds();
}
int* survivor_num=new int[par];//survivor_num為指向排在最后的par個人序號組成的數(shù)組的指針
for(int i=0;i<par;i++) Input>>survivor_num[i];//從文件中讀入par個人的序號
List list;
string name;
for(int j=0;j<total;j++)
{
Input>>name;//從文件中讀入total個人的名字
list.push_back(j+1,name);
}
int* survivor_list=new int[total-par];//survivor_list為指向滿足要求的Josephus排列的指針
//調(diào)用函數(shù)得到間隔人數(shù),并將其輸出到文件output.txt中
int distance=Josep(total,par,survivor_num,survivor_list);
Output<<distance<<endl;
for(int k=0;k<total-par;k++)
{//將前total-par個出列的人名字輸出到文件output.txt中
list.Retrieve(survivor_list[k],name);
Output<<name.c_str()<<endl;
}
delete[] survivor_num;
delete[] survivor_list;
Input.close();
Output.close();
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -