有n 个长为m+1 的字符串, 如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接, 问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误
http://www.haogongju.net/art/1670380
<?php
2 #有n个字符串,每个数组长度m+1,如果数组的后m个元素和另一个数组的前m个元素相同,则两个数组可以相连
3 #求n个数组中连接起来的最长路径是多少,如果遇到环路则报错退出
4
5 function longest($a, $m) {
6 $len = count($a);
7 #把二维数组$a的每个字符串元素看成一个节点
8 #建立节点之间的联通关系数组g,g[i][j]代表节点ij之间的最长路径
9
10 #初始化g,讲可连通的节点值设为1
11 $g = array();
12 for ($i = 0; $i < $len; $i++) {
13 for ($j = 0; $j < $len; $j++) {
14 $lastm = substr($a[$i], 1);
15 $firstm = substr($a[$j], 0, $m);
16 if ($lastm == $firstm) {
17 $g[$i][$j] = 1;
18 } else {
19 $g[$i][$j] = 0;
20 }
21 }
22 }
23
24 #使用弗洛伊德算法计算最长的路径
25 for ($k = 0; $k < $len; $k++) {
26 for ($i = 0; $i < $len; $i++) {
27 for ($j= 0; $j < $len; $j++) {
28 if ($g[$i][$k] > 0 && $g[$k][$j] > 0) {
29 $dist = $g[$i][$k] + $g[$k][$j];
30 if ($dist > $g[$i][$j]) {
31 $g[$i][$j] = $dist;
32 }
33 }
34 }
35 }
36 }
37
38 #检测环路
39 #环路包括两种,一种是i->i自己到自己,另一种是,i->...->k->...->i
40 for ($i = 0; $i < $len; $i++) {
41 if ($g[$i][$i] >= 1) die("There is a circle");
42 }
43
44 #求出最长路径
45 $max = 0;
46 for ($i = 0; $i < $len; $i++) {
47 $max = max(max($g[$i]), $max);
48 }
49
50 return $max;
51 }
52
53 $a = array(
54 "abcd",
55 "bcde",
56 "cdea",
57 "deab",
58 "eaba",
59 "abab",
60 "deac",
61 "cdei",
62 "bcdf",
63 "cdfi",
64 "dfic",
65 "cdfk",
66 "bcdg",
67 );
68
69 print_r(longest($a, 3));
70 ?>