找出字符串java中的递归模式

时间:2017-11-10 09:06:59

标签: java string algorithm data-structures pattern-matching

在我的一次采访中,我曾就java字符串问过一个程序,我无法回答。我不知道这是一个简单的程序还是复杂的程序。我已经在互联网上探索过它,但无法找到它的确切解决方案。我的问题如下,

我假设一个包含递归模式的字符串,如

String str1 = "abcabcabc";

在上面的字符串递归模式是“abc”,它在一个字符串中重复,因为这个字符串只递归地包含“abc”模式。

如果我将此字符串作为参数传递给函数/方法,函数/方法应该返回“此字符串具有递归模式。”如果该字符串没有任何递归模式,那么简单的函数/方法应返回“此字符串不包含递归模式。”

以下是概率,

String str1 = "abcabcabc"; 
//This string contains recursive pattern 'abc'

String str2 = "abcabcabcabdac"; 
//This string doesn't contains recursive pattern

String str2 = "abcddabcddabcddddabc";
//This string contains recursive pattern 'abc' & 'dd'

有人可以为我建议解决方案/算法,我正在努力解决它。不同概率的最佳方法是什么,以便我实现?

4 个答案:

答案 0 :(得分:3)

来自LeetCode

public boolean repeatedSubstringPattern(String str) {
  int l = str.length();
  for(int i=l/2;i>=1;i--) {
      if(l%i==0) {
          int m = l/i;
          String subS = str.substring(0,i);
          StringBuilder sb = new StringBuilder();
          for(int j=0;j<m;j++) {
              sb.append(subS);
          }
          if(sb.toString().equals(str)) return true;
      }
  }
  return false;
}
     
      
  1. 重复子字符串的长度必须是输入字符串长度的除数
  2.   
  3. 搜索str.length的所有可能除数,从length / 2开始
  4.   
  5. 如果i是长度的除数,则重复从0到i的子字符串i包含在s.length中的次数
  6.   
  7. 如果重复的子字符串等于输入str返回true
  8.   

答案 1 :(得分:1)

解决方案不在Javascript中。但是,问题看起来很有趣,所以试图在python中解决它。道歉!

python中,我写了一个有效的逻辑[可以写得更好,认为逻辑可以帮助你]

脚本

def check(lst):
    return all(x in lst[-1] for x in lst)

s = raw_input("Enter string:: ")
if check(sorted(s.split(s[0])[1:])):
    print("String, {} is recursive".format(s))
else:
    print("String, {} is NOT recursive".format(s))

脚本输出:

[mac] kgowda@blr-mp6xx:~/Desktop/my_work/play$ python dup.py 
Enter string:: abcabcabcabdac
String, abcabcabcabdac is NOT recursive
[mac] kgowda@blr-mp6xx:~/Desktop/my_work/play$ python dup.py 
Enter string:: abcabcabc
String, abcabcabc is recursive
[mac] kgowda@blr-mp6xx:~/Desktop/my_work/play$ python dup.py 
Enter string:: abcddabcddabcddddabc
String, abcddabcddabcddddabc is recursive

答案 2 :(得分:1)

这也可以使用Knuth–Morris–Pratt Algorithm的一部分来解决。

这个想法是建立一个一维数组,每个条目代表一个字符。对于单词中的每个字符i,我们检查是否有一个前缀也是单词up 0 to i中的后缀。原因是如果我们有共同的后缀和前缀,我们可以继续从前缀结束后的字符搜索,我们用相应的字符索引更新数组。

对于s="abcababcababcab",数组将为

Index : 0 1 2 3 4 5 6 7 8 
String: a b c a b c a b c 
KMP   : 0 0 0 1 2 3 4 5 6 

对于Index = 2,我们看到在ab

之前没有后缀也是字符串Index = 2中的前缀,即)

对于Index = 4,后缀ab(索引= 3,4)与前缀ab(索引= 0,1)相同,因此我们更新KMP[4] = 2,它是模式的索引我们必须继续搜索。

因此KMP[i]保存字符串s的索引,其中前缀匹配范围0 to i加1中的最长可能后缀。这实际上意味着长度为{{1的前缀先前存在于字符串中。使用这些信息,我们可以找出该长度的所有子串是否相同。

对于index + 1 - KMP[index],我们知道Index = 8,这意味着有一个长度KMP[index] = 6的前缀(s[3] to s[5]),它等于后缀(9 - 6 = 3 ),如果这是我们唯一的重复模式,那将遵循

如需更清楚地解释此算法,请check this video lecture。 该表可以在线性时间内构建,

s[6] to s[8]

答案 3 :(得分:0)

如果你知道&#39;部分&#39;提前,答案可能是Recursive regular expressions,似乎。

因此,对于abcabcabc,我们需要一个像abc(?R)*这样的表达式,其中:

  • abc匹配文字字符
  • (?R)递归模式
  • A *在零和无限次数之间匹配

第三个有点棘手。请参阅this regex101 link,但看起来像是:

((abc)|(dd))(?R)*

我们在哪里&#39; abc&#39;或者&#39; dd&#39;并且有许多这些。

否则,我不知道如何从字符串中确定它有一些未定义的递归结构。