【问题标题】:Find longest repeating substring with length between x and y查找长度在 x 和 y 之间的最长重复子串
【发布时间】:2013-02-08 10:06:03
【问题描述】:

给定一个字符串:“blablafblafbla”和 2 个限制:x=3,y=5 我想找到长度在 x 和 y 之间的最长重复子字符串。如果有很多,第一个 在我的例子中,这将是“blaf” 几个问题: 1.使用正则表达式更容易吗? 2.我知道如何找到最长的子字符串,但是我必须在哪里设置它在 x 和 y 之间的条件?

public static String longestDuplicate(String text)
{
    String longest = "";
    for (int i = 0; i < text.length() - 2 * longest.length() * 2; i++)
    {
        OUTER: for (int j = longest.length() + 1; j * 2 < text.length() - i; j++)
        {
            String find = text.substring(i, i + j);
            for (int k = i + j; k <= text.length() - j; k++)
            {
                if (text.substring(k, k + j).equals(find))
                {
                    longest = find;
                    continue OUTER;
                }
            }
            break;
        }
    }
    return longest;
}

【问题讨论】:

  • 很抱歉,您的控制语句错误。我强烈建议您在编写代码时学习更好的实践。你为什么要使用标签?那里真的需要一个“继续”语句,还是循环设计不同?
  • “坏”是什么意思?
  • @LuciC:此代码存在多个问题。几乎任何时候你必须使用定向breakcontinue,你想退后一步说“嗯,也许我在这里遇到了麻烦。” 特别是,如果您发现自己编写的循环永远不会真正循环,除非内部循环向它抛出一个定向的continue,就像您的循环标记为OUTER。在循环的终端条件中进行大量计算是另一个危险信号。但这只是codereview.stackexchange.com 的全部内容,而不是SO。 :-)
  • @LuciC:FWIW,该代码不起作用。它为给定的输入找到"bla" 而不是"blaf"pastie.org/6094127
  • 你是对的......我现在已经更正了。

标签: java string algorithm


【解决方案1】:

您提供的代码是解决您遇到的问题的一种极其低效的方法。我将使用Rabin-Karp 或其他一些滚动哈希算法来实现该解决方案,这将使您能够以O((y-x) * L) 的复杂性解决您的问题。

您不能在此处使用正则表达式 - 它们旨在解决完全不同的任务。

至于您关于如何使用您的解决方案查找长度在xy 之间的最长子字符串的问题,只需修改j 上的循环以仅考虑位于间隔[x, y]。这是你可以做到的。

for (int j = Math.max(longest.length() + 1, x) ; j * 2 < text.length() - i && j < y; j++)

编辑:要找到最长的子字符串,反转 for 循环:

for (int j = Math.min((text.length() - i -1)/2, y) ; j > longest.length() && j >=x; j--) 

【讨论】:

  • @T.J.Crowder 你为什么这么认为?我回答了关于如何有效解决问题的问题——使用 Rabin-Karp。我还添加了一些注释,这些注释可以是 cmets,但也适合这里。
  • 我知道它效率低下,但这将进一步集成到一些套接字算法中,jms,rmi,jsp,我只需要使用基本的东西
  • @T.J.Crowder 就在你写这篇文章的时候,我添加了最后一句关于在当前解决方案中应用限制。
  • @LuciC:一般来说,集成干净的代码会更幸运。当你有一个永远不会循环的循环,除非内部循环向它抛出 continue,你就知道你的代码有问题。 :-)
  • @IvayloStrandjev:你去。 :-)
【解决方案2】:
public static int commonPrefix (String string, int x, int y)
{
    int l = string.length ();
    int n = 0;
    int oy = y;
    while (x < oy && y < l && string.charAt (x) == string.charAt (y))
    {
        n++; x++; y++;
    }
    return n;
}

public static String longestRepeatingSubstring (
    String string, int minLength, int maxLength)
{
    String found = null; 

    int l = string.length ();
    int fl = minLength; 
    for (int x = 0; x < l - fl * 2; x++)
        for (int y = x + 1; y < l - fl; y++)
        {
            int n = commonPrefix(string, x, y);

            if (n >= maxLength)
                return string.substring(x, x + maxLength);

            if (n > fl)
            {
                found = string.substring (x, x + n);
                fl = n;
            }
        }

    return found;
}

public static void main(String[] args) {
    System.out.println (longestRepeatingSubstring ("blablafblafblafblaf", 3, 5));
}

【讨论】:

    【解决方案3】:

    这是一个使用正则表达式的笨拙实现:

    //import java.util.regex.*;
    
    public static String longestRepeatingSubstring (String string, int min, int max)
    {
      for (int i=max; i>=min; i--){
        for (int j=0; j<string.length()-i+1; j++){
    
          String substr = string.substring(j,j+i);
          Pattern pattern = Pattern.compile(substr);
          Matcher matcher = pattern.matcher(string);
    
          int count = 0;
          while (matcher.find()) count++;
    
          if (count > 1) return substr;
        }
      }
    
      return null;
    }
    
    public static void main(String[] args) {
      System.out.println (longestRepeatingSubstring ("blablafblafbla", 3, 5));
    }
    

    【讨论】:

      【解决方案4】:
          public static int getCount(String string , String subString){
      
          int count = 0;
          int fromIndex = 0;
          do{
          if(string.indexOf(subString, fromIndex) != -1){
              count++;
              fromIndex = string.indexOf(subString, fromIndex);
          }
          }while(fromIndex == string.length()-1);
          return count;
      }
      public static String longestRepeatingSubstring (int min,int max , String string){
          Vector substrs = new Vector();
          Vector substrs_length = new Vector();
          for (int i=min; i<=max; i++){
              for (int j=0; j<string.length()-i+1; j++){
                  String substr=string.substring(j, i+j);
                  System.out.println(substr);
                  if (substrs.indexOf(substr) == -1){
                      int count =getCount(string, substr);
                      if (count != 0) {
                          substrs.addElement(substr);
                          substrs_length.addElement(count);
                      }
                  }
              }
          }
          int maxLength = 0;
          int index = -1;
          for(int i = 0 ;  i < substrs_length.size() ; i++){
              int length = (int) substrs_length.elementAt(i);
              if(length > maxLength){
                  maxLength = length;
                  index = i;
              }
          }
          return (String) substrs.elementAt(index);
      }
      public static void main(String [] arg){
          System.out.print(longestRepeatingSubstring(3, 5, "blablafblafbla"));
      }
      

      【讨论】:

        猜你喜欢
        • 2016-08-11
        • 2020-03-22
        • 1970-01-01
        • 2015-03-02
        • 2014-12-04
        • 2012-05-08
        • 2020-10-03
        • 2021-08-29
        • 1970-01-01
        相关资源
        最近更新 更多