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

本文介绍了一个使用弗洛伊德算法解决字符串连接问题的方法,通过构造图结构来寻找一组字符串能够形成的最长链,并确保不存在循环依赖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有n 个长为m+1 的字符串, 如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接, 问这n 个

字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。

思路:利用弗洛伊德算法可求最长路径。

#include <iostream>
#include <string>
using namespace std;

#define INFINITY -100000   //求最长路径时,邻接矩阵初始化时应该设置成最小值

typedef struct graph
{
	string vertex[10];
	int arc[10][10];
	int num_vertex;
	int num_edge;
}graph;

int max=INFINITY,posi,posj;

bool largestpath(graph &g, int d[10][10], int p[10][10])
{
	int i,j,k,m;
	cout<<"请输入字符串个数:";
	cin>>g.num_vertex;
	cout<<"请输入字符串:";
	for(i=0;i<g.num_vertex;i++)
		cin>>g.vertex[i];
	cout<<"请输入m的值:";
	cin>>m;
	for(i=0;i<g.num_vertex;i++) //邻接矩阵初始化
		for(j=0;j<g.num_vertex;j++)
			g.arc[i][j] = INFINITY;
	for(i=0;i<g.num_vertex;i++)
		for(j=0;j<g.num_vertex;j++)
		{
			if(g.vertex[i].substr(g.vertex[i].size()-m,m) == g.vertex[j].substr(0,m))//首尾匹配,则成为一条边,权值为1
				g.arc[i][j] = 1;
			else
				g.arc[i][j] = INFINITY;
		}
	for(i=0;i<g.num_vertex;i++)
		for(j=0;j<g.num_vertex;j++)
		{
			d[i][j] = g.arc[i][j];
			p[i][j] = j;
		}
	for(k=0;k<g.num_vertex;k++)
		for(i=0;i<g.num_vertex;i++)
			for(j=0;j<g.num_vertex;j++)
			{
				if(d[i][j] < d[i][k]+d[k][j])//最长路径需要取最大值,这和求最短路径正好相反
				{
					d[i][j] = d[i][k]+d[k][j];
					p[i][j] = p[i][k];
				}
				if(d[i][j] > max) //记录当前最长路径
				{
					max = d[i][j];
					posi = i;
					posj = j;
				}
			}
	for(i=0;i<g.num_vertex;i++)//判断是否出现循环
		if(g.arc[i][i] != INFINITY)
			return false;
	return true;
}

int main()
{
	graph g;
	int d[10][10];
	int p[10][10];
	bool flag = largestpath(g,d,p);
	if(flag==false)
		cout<<"存在循环!"<<endl;
	else
	{
		cout<<"最长字符串链为:"<<endl;
		int num=0;
		int i = posi,j=posj;
		cout<<g.vertex[i];
		num++;
		int k = p[i][j];
		while(k!=j)
		{
			cout<<"->"<<g.vertex[k];
			k = p[k][j];
			num++;
		}
		cout<<"->"<<g.vertex[j]<<endl;
		num++;
		cout<<"最长字符串链长度为"<<num<<endl;
	}
	return 0;
}


 

 

参考:http://blog.csdn.net/cxllyg/article/details/7606599

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值