【问题标题】:Get all substrings which are unique获取所有唯一的子字符串
【发布时间】:2020-04-24 14:03:24
【问题描述】:

我正在开发一个程序,该程序计算给定输入字符串的所有可能的不同连续子字符串。

这是我的程序:

public int getAllUniqueSubset(String str) {
        Set<String> set = new HashSet<String>();
        for (int i = 0; i < str.length(); i++) {
            for (int j = 0; j < str.length() - i; j++) {
                String elem = str.substring(j, j + (i+1));
                if (!set.contains(elem)) {
                    set.add(elem);
                }
            }
        }
        return set.size();
    }

现在当我在几天前的在线考试中使用它时,它因超时错误而失败,因为输入字符串的长度可能高达 10 次方 5。

在这篇文章中也提出了类似的问题 - finding all distinct substring of a string 我也使用了相同的答案。

解决这个程序的正确方法是什么?

【问题讨论】:

  • 为什么投反对票?我可以看到添加 1-2 个示例的好处,但问题很明显

标签: java algorithm


【解决方案1】:

字符串长度 10^5 假设二次解太慢。您生成所有 n^2 个子字符串并计算它们的哈希值,因此总时间是三次方并且超时是可预期的。

您可以在 O(nlogn) 时间内构建后缀数组,然后使用 Kasai 方法或其他算法构建 LCP(最长公共前缀)。

我们可以看到每个后缀p[i] 的长度为n - p[i],并产生n - p[i] 前缀作为子字符串。但是lcp[i-1]前缀与前一个后缀的前缀一致!所以我们对于每个后缀只有n - p[i] - lcp[i-1] 新的inique 子串。遍历后缀并在 O(n) 时间内获取不同子字符串的计数。

总时间是

O(nlogn) (suffix array) + 
O(n) (Kasai LCP) + 
O(n) for counting = 
   O(nlogn)

【讨论】:

    【解决方案2】:

    一些想法,但可能不足以解决您的可扩展性问题:

    1. 您不需要if (!set.contains(elem)) 检查,因为这已经在set.add() 方法的逻辑中。需要一些时间来检查(甚至是恒定的)。

    2. 您可能希望将 Set 更改为 List(即使这涉及更大的空间消耗),并在最后转换为 set,以删除重复项。

    3. 似乎某些计算可以并行完成(例如,分配给工作人员执行长度为 1 的子字符串,分配给另一个长度为 2 的子字符串,等等)。这些不需要交叉检查(即,不需要检查每个工人的结果是否有重复)。例如,您可以尝试多线程或 Spark(如果并行化开销不大)。

    【讨论】:

      【解决方案3】:

      GeeksForGeeks试试这个解决方案

      public class GFG { 
          Set<String> set = new HashSet<String>();
          public static void SubString(String str, int n) 
          { 
              for (int i = 0; i < n; i++)  
                  for (int j = i+1; j <= n; j++) 
                      set.add(str.substring(i, j)); 
          } 
      
          public static void main(String[] args) 
          { 
              String str = "abcd"; 
              SubString(str, str.length()); 
          } 
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 2012-02-26
        • 2019-03-11
        • 1970-01-01
        相关资源
        最近更新 更多