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

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值