您的位置:首页 > 编程语言

一笔画游戏路径搜索代码<未优化>

2015-09-01 20:09 597 查看
#include <iostream>

#include <vector>

#include <string>

#include <algorithm>

#include <stack>

using namespace std;

//*******************************************************************************************

/*

* 穷取法寻找一条路径,若等于输入的边数则成功退出;

*

*/

class GraphicData

{

public:

int signal; //边索引号。

char nodea; //节点a。

char nodeb; //节点b。

int oriFir; //是否有方向(0:无,1:有,2:可变)。

int oriSec; //节点指向(0:a->b,1:b->a)。

int byCount; //边可通过次数 :1,2。

public:

GraphicData(){}

GraphicData(int s,int na,int nb,int or,int oc,int bt)

{

signal=s;

nodea=na;

nodeb=nb;

oriFir=or;

oriSec=oc;

byCount=bt;

}

};

typedef struct Table

{

vector<GraphicData> v; //存储容器表

int seq; //存储遍历深度

int dir; //存储方向0:a,1:b

}Ta;

typedef struct CharData

{

char element; //存储字符

int seq; //与Table 中索引一致

}CDa;

//********************************************************************************************

/*在容器中查找字符,将结果返回到迭代器中

* a: 查找字符 ;

* nextValue: 查找下一字符 ;

* hse: 判断是否还有未扫描的边

*/

//容器中查找字符,返回bool值

bool findElem(vector<char>&vec,char seq)

{

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

{

if((*it)==seq)

return true;

}

return false;

}

//查找字符,返回查找到的迭代器和指向

bool findChar(vector<GraphicData>&vec,vector<GraphicData>::iterator &it,char &Value,int &nextSig,int &hse,vector<char>& veceng)

{

hse=0;

while(it<vec.end())

{

//判断边是否可以通过

if((*it).byCount>0)

{

hse=1;

//判断方向:有(0);无(1);其中可变被包含

if((*it).oriFir==0)

{

if((*it).nodea==Value &&!findElem(veceng,(*it).nodeb))

{

nextSig=1;

return true;

}

else if((*it).nodeb==Value&&!findElem(veceng,(*it).nodea))

{

nextSig=0;

return true;

}

}

else if((*it).oriFir==1)

{

if((*it).oriSec==0)

{

if((*it).nodea==Value &&!findElem(veceng,(*it).nodeb))

{

nextSig=1;

return true;

}

}

else

{

if((*it).nodeb==Value &&!findElem(veceng,(*it).nodea))

{

nextSig=0;

return true;

}

}

}

else if((*it).oriFir==2)

{

if((*it).oriSec==0)

{

if((*it).nodea==Value &&!findElem(veceng,(*it).nodeb))

{

nextSig=1;

return true;

}

}

else

{

if((*it).nodeb==Value &&!findElem(veceng,(*it).nodea))

{

nextSig=0;

return true;

}

}

}

}

it++;

}

return false;

}

//交换两元素的位置

template<typename T> void swap2(T &a,T &b)

{

T temp=a; a=b; b=temp;

}

//计算总路径(包括重复的边)

int sumEdge(vector<GraphicData>&vec)

{

int sum=0;

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

{

sum+=(*it).byCount;

}

return sum;

}

//查找字符,返回迭代器

void findIterator(vector<GraphicData>&vec,vector<GraphicData>::iterator &st,int seq)

{

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

{

if((*it).signal==seq)

{

st=it;

break;

}

}

}

//查找可变的边

void findVariable(vector<GraphicData>&vec,vector<char> &v)

{

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

{

if((*it).oriFir==2)

{

if((*it).oriSec==0)

v.push_back((*it).nodea);

else

v.push_back((*it).nodeb);

}

}

}

//修改Table里面的值

void AlterVariable(vector<GraphicData>&vec,char &c)

{

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

{

if((*it).oriFir==2)

{

if((*it).oriSec==0 &&(*it).nodea==c)

{

(*it).oriFir=1;

(*it).oriSec=1;

break;

}

else if((*it).oriSec==1 &&(*it).nodeb==c)

{

(*it).oriFir=1;

(*it).oriSec=0;

break;

}

}

}

}

//根据指定元素查找其他元素

/*

*tempvec:存储结果

*sig :指示方向 0:a 1:b

*/

bool runFinder(vector<GraphicData>&vec,

vector<GraphicData>::iterator st,

vector<CharData> &tempvec,

const int sig)

{

stack<Table> sktable; //存储元素表

stack<vector<GraphicData>::iterator> sktg;//存储元素索引

Table vt;

CharData ca;

char tempc='0';

int nextSig=0; //下一个索引的方向

tempvec.clear(); //清空缓存

vector<char> veceng; //保存同一层

vector<char> v2; //存储可变的边

findVariable(vec,v2);

// cout<<"输出2的节点"<<endl;

// for(int i=0;i<v2.size();i++)

// cout<<v2[i]<<" ";

// cout<<endl;

//若开始就有方向可变边的节点,则后面的表要改变方向

(*st).byCount--;

if(v2.size()>0)

{

if(sig==1)

{

if(findElem(v2,(*st).nodeb))

{

AlterVariable(vec,(*st).nodeb);

}

}

else

{

if(findElem(v2,(*st).nodea))

{

AlterVariable(vec,(*st).nodea);

}

}

}

//存储起始节点(0:a,1:b)

if(sig==0)

{

ca.element=(*st).nodeb;

ca.seq=1;

tempvec.push_back(ca);

vt.dir=0;

vt.seq=1;

vt.v=vec;

sktable.push(vt);

//cout<<"进栈: "<<(*st).nodea<<endl;

}

else

{

ca.element=(*st).nodea;

ca.seq=1;

tempvec.push_back(ca);

vt.dir=1;

vt.seq=1;

vt.v=vec;

sktable.push(vt);

// cout<<"进栈: "<<(*st).nodeb<<endl;

}

sktg.push(st);

//循环遍历以该节点为首的序列

long depth=1; //记录深度

bool isSuccess=true;

vector<GraphicData>::iterator tt;

vector<GraphicData> veccopy=vec;

while(!sktg.empty())

{

veceng.clear();

vt=sktable.top();

tt=sktg.top();

// if(vt.dir==0)

// cout<<"出栈: "<<(*tt).nodea<<endl;

// else

// cout<<"出栈: "<<(*tt).nodeb<<endl;

sktable.pop();

sktg.pop();

++depth;

//若路径失败,刷新容器

if(!isSuccess)

{

for(vector<CharData>::iterator it=tempvec.end()-1;it>=tempvec.begin();it--)

{

if((*it).seq==vt.seq)

{

for(vector<CharData>::iterator st=it+1;st!=tempvec.end();)

{

st=tempvec.erase(st++);

}

break;

}

}

}

//存储出栈的字符

if(vt.dir==0)

{

tempc=(*tt).nodea; //存储下一字符

ca.element=(*tt).nodea;

ca.seq=depth;

tempvec.push_back(ca);

}

else

{

tempc=(*tt).nodeb;//存储下一字符

ca.element=(*tt).nodeb;

ca.seq=depth;

tempvec.push_back(ca);

}

int isFind=0; //判断循环是否执行

int nes=0; //判断是否还有未扫描的边

vector<GraphicData> tempv=vt.v;

tt=tempv.begin();

char temchild='0';

while(findChar(tempv,tt,tempc,nextSig,nes,veceng))

{

isFind=1;

if((*tt).oriFir==2)

{

if((*tt).oriSec==1)

(*tt).oriSec=0;

else

(*tt).oriSec=1;

}

(*tt).byCount--;

if(nextSig==0)

temchild=(*tt).nodea;

else

temchild=(*tt).nodeb;

//cout<<"进栈: "<<temchild<<endl;

veceng.push_back(temchild);

if(v2.size()>0)

{

if(nextSig==0)

{

if(findElem(v2,(*tt).nodea))

{

AlterVariable(tempv,(*tt).nodea);

}

}

else

{

if(findElem(v2,(*tt).nodeb))

{

AlterVariable(tempv,(*tt).nodeb);

}

}

}

Table vtt;

vtt.dir=nextSig;

vtt.seq=depth;

vtt.v=tempv;

sktable.push(vtt);

vector<GraphicData>::iterator ttmp;

findIterator(veccopy,ttmp,(*tt).signal);

sktg.push(ttmp);

tempv=vt.v;

tt=tempv.begin();

}

if(nes==0)

{

cout<<"--Result: find success!"<<endl;

return true; //路径成功,返回

}

else if(isFind==0 && nes==1)

{

isSuccess=false; //路径失败!

}

}

return false;

}

void main()

{

int noScanCount=0; //定义是否有未扫描的边数,若为0,则成功;

cout<<"*****************************************"<<endl;

vector<GraphicData> vec1;

vec1.clear();

int i=0;

//cout<<"--Please enter bilateral relations! "<<endl;

cout<<"--Format: <int signal,char nodea, char nodeb,int oriFir,int oriSec,int byCount> "<<endl;

cout<<" --signal : bilateral index number."<<endl;

cout<<" --nodea : node a."<<endl;

cout<<" --nodeb : node b."<<endl;

cout<<" --oriFir : direction(0:no; 1:yes; 2:variable."<<endl;

cout<<" --oriSec : node direction(0:a->b,1:b->a)."<<endl;

cout<<" --byCount: the number of side which can be able to go"<<endl;

/*while(i++<num)

{

cin>>data.signal>>data.nodea>>data.nodeb>>data.oriFir>>data.oriSec>>data.byCount;

vec1.push_back(data);

}

*/

//**************************测试**********************************

/*

GraphicData data4(4,'c','d',2,0,2);

GraphicData data5(5,'a','b',0,0,1);

GraphicData data3(3,'a','c',2,0,2);

GraphicData data2(2,'a','d',0,0,2);

GraphicData data1(1,'c','b',1,0,1);

vec1.push_back(data1);

vec1.push_back(data2);

vec1.push_back(data3);

vec1.push_back(data4);

vec1.push_back(data5);

*/

GraphicData data1(1,'a','c',0,0,1);

GraphicData data2(2,'d','b',0,0,1);

GraphicData data6(3,'a','b',0,0,2);

GraphicData data7(4,'c','d',0,0,2);

GraphicData data3(5,'a','j',0,0,1);

GraphicData data4(6,'c','k',0,0,1);

GraphicData data5(7,'b','m',0,0,1);

GraphicData data8(8,'d','l',0,0,1);

GraphicData data9(9,'f','n',0,0,2);

GraphicData data10(10,'i','n',0,0,2);

GraphicData data11(11,'e','n',0,0,1);

GraphicData data12(12,'n','h',1,0,2);

GraphicData data13(13,'k','f',1,0,2);

GraphicData data14(14,'k','h',0,0,1);

GraphicData data15(15,'h','l',0,0,1);

GraphicData data16(16,'l','i',1,0,2);

GraphicData data17(17,'i','m',0,0,2);

GraphicData data18(18,'m','e',0,0,1);

GraphicData data19(19,'e','j',0,0,1);

GraphicData data20(20,'j','f',0,0,2);

vec1.push_back(data1);

vec1.push_back(data2);

vec1.push_back(data3);

vec1.push_back(data4);

vec1.push_back(data5);

vec1.push_back(data6);

vec1.push_back(data7);

vec1.push_back(data8);

vec1.push_back(data9);

vec1.push_back(data10);

vec1.push_back(data11);

vec1.push_back(data12);

vec1.push_back(data13);

vec1.push_back(data14);

vec1.push_back(data15);

vec1.push_back(data16);

vec1.push_back(data17);

vec1.push_back(data18);

vec1.push_back(data19);

vec1.push_back(data20);

//***************************************************************

vector<GraphicData> vec2=vec1;

cout<<"--show bilateral inputed!"<<endl;

for(vector<GraphicData>::iterator it=vec2.begin();it!=vec2.end();it++)

cout<<" ("<<(*it).signal<<","<<(*it).nodea<<","<<(*it).nodeb<<","<<(*it).oriFir<<","<<(*it).oriSec<<","<<(*it).byCount<<")"<<endl;

//<1>每遍历一个data,则其可通过次数-1,若容器中每个元素可通过次数都为0,则路径正确。

//<2>若是方向可变边,扫描一次时,将其oriSec改变即可。

int c2=sumEdge(vec2); //总路径

cout<<"--TotalPath: "<<c2<<endl;

vector<CharData> tempvec; //存储正确的连接顺序

vector<GraphicData>::iterator st=vec2.begin(); //遍历迭代器

vector<GraphicData>::iterator stb=vec2.begin();

while(stb!=vec2.end())

{

noScanCount=0;

if((*stb).oriFir==0)

{

if(runFinder(vec2,st,tempvec,0)) //0:a,1:b

{

noScanCount=1;

break;

}

else

{

vec2=vec1;

st=stb;

if(runFinder(vec2,st,tempvec,1))

{

noScanCount=1;

break;

}

}

}

else

{

if((*stb).oriSec==0)

{

if(runFinder(vec2,st,tempvec,1))

{

noScanCount=1;

break;

}

}

else

{

if(runFinder(vec2,st,tempvec,0))

{

noScanCount=1;

break;

}

}

}

stb++;

st=stb;

vec2=vec1;

}

if(noScanCount==1)

{

cout<<" ";

for(vector<CharData>::iterator it=tempvec.begin();it!=tempvec.end();it++)

cout<<" "<<(*it).element<<" ->";

}

cout<<endl;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: