2013-02-08 48 views
4

给定一个字符串:“blablafblafbla”和2个限制:x = 3,y = 5 我想找到长度在x和y之间的最长重复子字符串。有很多,第一个 在我的例子中,这将是“blaf” 几个问题: 1.是否更容易使用正则表达式? 2.我知道如何找到最长的子字符串,但我必须把它的条件放在x和y之间?查找长度在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; 
} 
+1

我抱歉,您的控制语句是_bad_。我强烈建议您在编写代码时学习更好的实践。你为什么使用标签?真的需要一个'继续'的声明,或者循环的设计是否有所不同? –

+0

这是什么意思“坏”? –

+1

@LuciC:这段代码有多个问题。几乎任何时候你必须使用定向的“break”或“continue”,你想退一步说“嗯,也许我在这里遇到了一些麻烦。” *特别是*如果你发现自己编写的循环永远不会实际循环,除非一个内部循环抛出一个定向的'continue',就像你的循环标记为'OUTER'一样。在回路的终端条件下进行重要计算是另一个危险信号。但这是http://codereview.stackexchange.com所有的东西,不是SO。 :-) –

回答

2

您提供的代码是解决您所遇到问题的极其低效的方法。我会使用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 (int j = Math.min((text.length() - i -1)/2, y) ; j > longest.length() && j >=x; j--) 
+0

@ T.J.Crowder你为什么这么认为?我回答了关于如何有效解决问题的问题 - 使用Rabin-Karp。我还添加了一些注释,可以**可以评论,但也适用于此。 –

+0

我知道这是效率低下,但这将进一步集成到一些套接字算法,jms,rmi,jsp和我只需要使用基本的东西 –

+0

@TJCrowder就像你写的那样我添加了最后一句话,解。 –

1
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)); 
} 
+0

谢谢你的替代解决方案......效果很好 –

1

这里是一个笨拙的实现与正则表达式:

//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)); 
} 
0
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")); 
}