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

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

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

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

    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. }  


  • 相关阅读:
    poj 3320 Jessica's Reading Problem
    uva 120 C
    vim使用教程-转自
    2015 俄罗斯网络赛 D. Boulevard
    HTML转义字符大全
    介绍个好点的,JAVA技术群
    JAVA学习路线
    linux常用命令大全(转)好东西要分享
    Jqprint 轻量级页面打印插件
    hadoop集群搭建
  • 原文地址:https://www.cnblogs.com/mfryf/p/2652112.html
Copyright © 2011-2022 走看看