模糊距离分析 及 java代码实现

来源:互联网 发布:淘宝女装店的现状分析 编辑:程序博客网 时间:2024/06/03 06:29

模糊距离分析

原题

X和Y都是只有0和1组成的字符串。D(X,Y)称为模糊距离,定义如下:首先删除X和Y从头开始的公共子串然后将X和Y剩下部分的长度相加得到模糊距离例如D(1000,1111),首先,删除子串“1”,然后剩下“000”和“111”长度都是3,相加为6,则D(1000,1111)=6。例如D(101,1100),首先删除公共子串“1”,然后剩下"01"和"100"长度分别为2,3,相加为5,则D(101,1100)=5。

问题是,给定n个只有0和1的字符串,如:111110001011100...请找到最大的模糊距离,字符串总数为n,字符串最长为m。

分析

这个题目描述比较长,但实际上,并不难。只要耐心,看完题目,即可。描述也不晦涩。

直接想来,对于每一个01字符串,与其他的每一个01字符串进行模糊距离的计算,时间复杂度是O(nm),遍历完n个字符串,总的时间复杂度是O(n^2*m)。这个我们可以称为暴力法。

如何改进上面的方法的,主要是指缩小时间复杂度。一个非常通用的方法,就是以空间换时间。如何换呢?对于模糊距离的第一个条件,我们想到什么呢?公共前缀,不知道同学们,联想到树形结构:trie树没有。例如:给定000、001、0010,我们构造如下的trie树。

 0    0  1 00   

构造过程中,1为左子树,0为右子树。模糊距离的第一个条件是,去掉公共前缀,则计算时,两个字符串,要有公共前缀,也就意味着,只需要考虑开始分叉的节点,左右子树,可以有一个没有。这样,我们考虑第一个分叉的节点:0,然后可以计算第二部分了,如何计算剩下长度相加呢?尤其,为了找到模糊距离的最大值,我们求得当前节点的左子树的最大深度以及右子树的最大深度,两者相加,及得到一个模糊距离,为3。然后考虑1节点,右子树为空,则模糊距离为1。综合,最大的模糊距离为3。这里有一个小小的技巧,构建的过程中,可以在节点中,存储左右子树的高度,并随着加入新的字符串,更新左右子树的高度。总的时间复杂度为O(nm)。 根据上例,存储的左右子树的高度值变化如下 (left_height, right_height):

  • left_height: 左边子树的高度

  • right_height: 右边子树的高度

 0(0,2)    0(0,1)    0(0,0) 0(0,2)    0(1,1)  1(0,0) 0(0,0) 0(3,2)    0(2,1)  1(1,0) 0(0,0)0(0,0)   

【分析完毕】

package Array;import Tree.Node;/** * @Title: MoHU_juli.java * @Package Array * @Description: X和Y都是只有0和1组成的字符串。D(X,Y)称为模糊距离,定义如下: 首先删除X和Y从头开始的公共子串 *               然后将X和Y剩下部分的长度相加得到模糊距离 *               例如D(1000,1111),首先,删除子串“1”,然后剩下“000”和“111”长度都是3,相加为6,则 *               D(1000,1111)=6。 *               例如D(101,1100),首先删除公共子串“1”,然后剩下"01"和"100"长度分别为2,3,相加为5,则 *               D(101,1100)=5。 *  *               问题是,给定n个只有0和1的字符串,如: 1111 1000 101 1100 ... *               请找到最大的模糊距离,字符串总数为n,字符串最长为m。 * @author nutc * @date 2013-8-17 下午8:37:43 * @version V1.0 */public class MoHU_juli {public static void main(String args[]){int [][] a = {{1,1,1,1},{1,1,0,0,1},{1,1,1,0,0,0}};System.out.println("模糊距离为"+findDis(a));int [][] b = {{1,1,1,1},{1,0,0,0}};System.out.println("模糊距离为"+findDis(b));}public static int findDis(int[][] val) {if (val == null)return 0;Node tree = new Node(-1);for (int i = 0; i < val.length; i++) {buildTree(tree, val[i]);}//tree.display();Result re = findMax(tree);return re.max;}public static void buildTree(Node root, int[] num) {if (num == null)return;Node now = root;for (int i = 0; i < num.length; i++) {int val = num[i];if (val == 1) {if (now.right == null) {Node n = new Node(1);now.right = n;}now = now.right;} else {if (now.left == null) {Node n = new Node(0);now.left = n;}now = now.left;}}}public static class Result {int max;int height;}public static Result findMax(Node n) {Result r = new Result();if (n == null) {r.height = 0;r.max = 0;}else{Result left = findMax(n.left);Result right = findMax(n.right);r.height = (left.height>right.height? left.height:right.height)  +1;int nowdis = left.height + right.height;  //注意模糊距离的概念! 所以应该是相加!!!r.max = left.max>right.max?left.max:right.max;r.max = r.max>nowdis? r.max:nowdis;}return r;}}


举报该文章

原创粉丝点击