zoukankan      html  css  js  c++  java
  • 求N个字符串的最大公共子串

    今天在一个perl论坛上面看到了这个题目,说是微软的面试题。用javascript写了一个实现,可能效率不是很高,回去研究研究模式匹配算法先~

    <script>
    var s1 = "drhe123rherhert346",
    s2 = "hxert32344",
    n = 0, t, max_len = 0, match_hash =
    {
    }
    ,
    s_loop = s1.length > s2.length ? s2 : s1,
    s_test = s1.length > s2.length ? s1 : s2;
    for(var i = 0; i < s_loop.length && max_len <= s_loop.length - i - 1; i ++ )
    {
    for(var j = 0; j < s_loop.length - i && max_len <= s_loop.length - i - j - 1; j ++ )
    {
    t = s_loop.slice(i, s_loop.length - j);
    if(new RegExp(t, "g").test(s_test))
    {
    match_hash[t.length] = match_hash[t.length] ? match_hash[t.length] + "," + t : t;
    if(t.length > max_len)max_len = t.length;
    }
    n ++ ;
    }
    n ++ ;
    }
    document.write("字串1:" + s1 + "<br>字串2:" + s2 + "<br>循环次数:" + n + "<br>最大子串:" + match_hash[max_len]);
    </script>

    运行结果:

    字串1:drhe123rherhert346
    字串2:hxert32344
    循环次数:35
    最大子串:ert3

    上次没有说思路,这里一起说下吧:
    1:先从参与匹配的N个字符串中选出长度最小的字符串。定义一个max_len用来记录公共子串长度。
    2(循环一):拿长度最小的字符串开刀:分割出所有子串,如“abcd”的子串有abcd,abc,ab,abcd,bc,bcd,cd如果剩下的长度小于max_len,则没有必要再继续分割,退出循环,这句话比较难于理解,体现在下面两个外层循环的for表达式中,加粗部分
    3(循环二):把上面的子串分别与剩下的参与匹配的字符串进行匹配,如果有一个不符合,跳出循环。如果都符合,则为公共子串。
    4:如果有一个子串为公共子串:
    把这个子串按照“长度(int)=>字符串(string)”的形式存在哈希表match_hash中;
    同时记录子串中的最大长度:max_len
    5:从哈希表中取出max_len的值match_hash[max_len]即为最大公共子串。

    <script>
    function max_match()
    {
    var arr = [], i = 0, n = 0, max_len = 0, t, is_match = false;
    match_hash =
    {
    }
    ;
    while(i < arguments.length)
    {
    arr[i] = arguments[i];
    i ++ ;
    }
    arr.sort(function(a, b)
    {
    return a.length > b.length ? 1 : - 1;
    }
    );
    for(var i = 0; i < arr[0].length && max_len <= arr[0].length - i - 1; i ++ )
       {
          for(var j = 0; j < arr[0].length - i && max_len <= arr[0].length - i - j - 1; j ++ )
          {
             t = arr[0].slice(i, arr[0].length - j);
    for(var k = 1; k < arr.length; k ++ )
    {
    is_match = new RegExp(t, "g").test(arr[k]);
    if( ! is_match)
    break;
    // 累加循环次数
                n ++ ;
    }
    if(is_match)
    {
    match_hash[t.length] = match_hash[t.length] ? match_hash[t.length] + "," + t : t;
    if(t.length > max_len)max_len = t.length;
    }
    // 累加循环次数
    n ++ ;
    }
    // 累加循环次数
          n ++ ;
    }
       /* 返回结果 */
    if(max_len > 0)
    {
    return "参与匹配的子串:<br>"
    // 为最大公共子串着色
    + arr.join("<br>").replace(new RegExp("(" + match_hash[max_len].replace(/,/, "|") + ")", "ig"), "<font color=#FF0000><b>$1<\/b><\/font>") + "<br><br>"
    + "最大子串:" + match_hash[max_len] + "<br>"
    + "循环次数:" + n;
    }
    else
    {
    return "未找到!";
    }
    }
    document.write(max_match("奇妙的Javascript图片放大镜", "JavaScript是个脚本编程语言", "JavaScript正在成为Ruby杀手? ", "在网站上应用的JavaScript越来越多"));
    </script>

    运行结果:

    参与匹配的子串:
    JavaScript是个脚本编程语言
    奇妙的Javascript图片放大镜
    在网站上应用的JavaScript越来越多
    JavaScript正在成为Ruby杀手?

    最大子串:cript
    循环次数:117

  • 相关阅读:
    L2-1 功夫传人 (25分)
    7-11 家庭房产(25 分)
    7-11 玩转二叉树 (25分)
    7-10 排座位 (25分)
    7-12 最长对称子串 (25分)
    7-10 树的遍历 (25分)
    STL
    Max Gcd
    水果
    Rails
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1772223.html
Copyright © 2011-2022 走看看