有n 个长为m+1 的字符串,求前后m个字符匹配所能形成的最长字符串链:利用弗洛伊德算法求最长路径...

有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接,问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。

把字符串看成图中的一个顶点,两字符串匹配则两个顶点间有边,从而转化为图的问题。

利用弗洛伊德算法求图的最长路径。

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. #define INFINITY -10000    
  6. #define MAX_VERTEX_NUM 20   
  7.   
  8. typedef struct MGraph{  
  9.     string vexs[MAX_VERTEX_NUM];//顶点信息,这里就是要处理的字符串,每个字符串看做一个顶点  
  10.     int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵,符合条件的两个字符串之间有边  
  11.     int vexnum, arcnum;//顶点数就是字符串的个数  
  12. }MGraph;  
  13.   
  14. void CreateDG(MGraph &G)//构造有向图  
  15. {  
  16.     int i, j;  
  17.     int m;  
  18.     cout<<"请输入要处理的字符串个数:";  
  19.     cin>>G.vexnum;  
  20.   
  21.     cout<<"请输入这"<<G.vexnum<<"个字符串:";  
  22.     for(i=0; i<G.vexnum; i++)  
  23.         cin>>G.vexs[i];  
  24.   
  25.     cout<<"请输入m:";  
  26.     cin>>m;  
  27.   
  28.     for(i=0; i<G.vexnum; i++)  
  29.         for(j=0; j<G.vexnum; j++)  
  30.         {  
  31.             if(G.vexs[i].substr(G.vexs[i].size()-m,m)==G.vexs[j].substr(0,m))//根据前后m个字符是否匹配确定两字符串之间是否有边  
  32.                 G.arcs[i][j]=1;  
  33.             else  
  34.                 G.arcs[i][j]=INFINITY;  
  35.         }  
  36. }  
  37.   
  38. //利用弗洛伊德算法求各顶点间的最长路径,p保存路径,D保存各顶点间的最长路径,如果出现循环,函数返回false,反之返回true  
  39. bool Largeset_FLOYD(MGraph G, int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM], int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM])  
  40. {  
  41.     int v, w, u;  
  42.     int i, j;  
  43.   
  44.     for(v=0; v<G.vexnum; v++)  
  45.         for(w=0; w<G.vexnum; w++)  
  46.         {  
  47.             D[v][w]=G.arcs[v][w];  
  48.             for(u=0; u<G.vexnum; u++)  
  49.                 p[v][w][u]=-1;  
  50.             if(D[v][w]>INFINITY)  
  51.             {  
  52.                 p[v][w][0]=v;  
  53.                 p[v][w][1]=w;  
  54.             }  
  55.         }  
  56.   
  57.     for(u=0; u<G.vexnum; u++)  
  58.         for(v=0; v<G.vexnum; v++)  
  59.             for(w=0; w<G.vexnum; w++)  
  60.             {  
  61.                 if(D[v][u]>INFINITY && D[u][w]>INFINITY && D[v][u]+D[u][w]>D[v][w] )//改进的弗洛伊德算法,求最长路径  
  62.                 {  
  63.                     D[v][w]=D[v][u]+D[u][w];  
  64.   
  65.                     //更新p,以便打印路径  
  66.                     for(i=0; i<G.vexnum; i++)  
  67.                     {  
  68.                         if(p[v][u][i]!=-1)  
  69.                             p[v][w][i]=p[v][u][i];  
  70.                         else  
  71.                             break;  
  72.                     }  
  73.                     for(j=1; j<G.vexnum; j++)  
  74.                     {  
  75.                         if(p[u][w][j]!=-1)  
  76.                             p[v][w][i++]=p[u][w][j];  
  77.                         else  
  78.                             break;  
  79.                     }  
  80.                       
  81.                 }  
  82.             }  
  83.   
  84.     //判断是否有循环  
  85.     for(v=0; v<G.vexnum; v++)  
  86.         if(D[v][v]!=INFINITY)  
  87.                 return false;  
  88.       
  89.     return true;  
  90. }  
  91.   
  92. void main()  
  93. {  
  94.     int i, j;  
  95.     int posx, posy;  
  96.     MGraph g;  
  97.     CreateDG(g);  
  98.   
  99.     int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];  
  100.     int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  
  101.     bool flag=true;  
  102.   
  103.     flag=Largeset_FLOYD(g, p, D);  
  104.   
  105. /*  for(i=0; i<g.vexnum; i++) 
  106.     { 
  107.         for(j=0; j<g.vexnum; j++) 
  108.             cout<<D[i][j]<<" "; 
  109.         cout<<endl; 
  110.     }*/  
  111.   
  112.       
  113.     if(flag)  
  114.     {  
  115.         cout<<"最大长度为:";  
  116.         int max=-10000;  
  117.         for(i=0; i<g.vexnum; i++)  
  118.             for(j=0; j<g.vexnum; j++)  
  119.             {  
  120.                 if(D[i][j]>max)  
  121.                 {  
  122.                     max=D[i][j];  
  123.                     posx=i;  
  124.                     posy=j;  
  125.                 }  
  126.             }  
  127.         cout<<max<<endl;  
  128.         cout<<"字符串链为:";  
  129.         for(i=0; i<g.vexnum; i++)//打印字符串链  
  130.         {  
  131.             if(p[posx][posy][i]!=-1)  
  132.                 cout<<g.vexs[p[posx][posy][i]]<<" ";  
  133.         }  
  134.         cout<<endl;  
  135.     }  
  136.     else  
  137.         cout<<"错误:出现循环"<<endl;  
  138.   
  139. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值