有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接,问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
把字符串看成图中的一个顶点,两字符串匹配则两个顶点间有边,从而转化为图的问题。
利用弗洛伊德算法求图的最长路径。
- #include <iostream>
- #include <string>
- using namespace std;
- #define INFINITY -10000
- #define MAX_VERTEX_NUM 20
- typedef struct MGraph{
- string vexs[MAX_VERTEX_NUM];//顶点信息,这里就是要处理的字符串,每个字符串看做一个顶点
- int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵,符合条件的两个字符串之间有边
- int vexnum, arcnum;//顶点数就是字符串的个数
- }MGraph;
- void CreateDG(MGraph &G)//构造有向图
- {
- int i, j;
- int m;
- cout<<"请输入要处理的字符串个数:";
- cin>>G.vexnum;
- cout<<"请输入这"<<G.vexnum<<"个字符串:";
- for(i=0; i<G.vexnum; i++)
- cin>>G.vexs[i];
- cout<<"请输入m:";
- cin>>m;
- for(i=0; i<G.vexnum; i++)
- for(j=0; j<G.vexnum; j++)
- {
- if(G.vexs[i].substr(G.vexs[i].size()-m,m)==G.vexs[j].substr(0,m))//根据前后m个字符是否匹配确定两字符串之间是否有边
- G.arcs[i][j]=1;
- else
- G.arcs[i][j]=INFINITY;
- }
- }
- //利用弗洛伊德算法求各顶点间的最长路径,p保存路径,D保存各顶点间的最长路径,如果出现循环,函数返回false,反之返回true
- bool Largeset_FLOYD(MGraph G, int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM], int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM])
- {
- int v, w, u;
- int i, j;
- for(v=0; v<G.vexnum; v++)
- for(w=0; w<G.vexnum; w++)
- {
- D[v][w]=G.arcs[v][w];
- for(u=0; u<G.vexnum; u++)
- p[v][w][u]=-1;
- if(D[v][w]>INFINITY)
- {
- p[v][w][0]=v;
- p[v][w][1]=w;
- }
- }
- for(u=0; u<G.vexnum; u++)
- for(v=0; v<G.vexnum; v++)
- for(w=0; w<G.vexnum; w++)
- {
- if(D[v][u]>INFINITY && D[u][w]>INFINITY && D[v][u]+D[u][w]>D[v][w] )//改进的弗洛伊德算法,求最长路径
- {
- D[v][w]=D[v][u]+D[u][w];
- //更新p,以便打印路径
- for(i=0; i<G.vexnum; i++)
- {
- if(p[v][u][i]!=-1)
- p[v][w][i]=p[v][u][i];
- else
- break;
- }
- for(j=1; j<G.vexnum; j++)
- {
- if(p[u][w][j]!=-1)
- p[v][w][i++]=p[u][w][j];
- else
- break;
- }
- }
- }
- //判断是否有循环
- for(v=0; v<G.vexnum; v++)
- if(D[v][v]!=INFINITY)
- return false;
- return true;
- }
- void main()
- {
- int i, j;
- int posx, posy;
- MGraph g;
- CreateDG(g);
- int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
- int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
- bool flag=true;
- flag=Largeset_FLOYD(g, p, D);
- /* for(i=0; i<g.vexnum; i++)
- {
- for(j=0; j<g.vexnum; j++)
- cout<<D[i][j]<<" ";
- cout<<endl;
- }*/
- if(flag)
- {
- cout<<"最大长度为:";
- int max=-10000;
- for(i=0; i<g.vexnum; i++)
- for(j=0; j<g.vexnum; j++)
- {
- if(D[i][j]>max)
- {
- max=D[i][j];
- posx=i;
- posy=j;
- }
- }
- cout<<max<<endl;
- cout<<"字符串链为:";
- for(i=0; i<g.vexnum; i++)//打印字符串链
- {
- if(p[posx][posy][i]!=-1)
- cout<<g.vexs[p[posx][posy][i]]<<" ";
- }
- cout<<endl;
- }
- else
- cout<<"错误:出现循环"<<endl;
- }