java 查找字符串中的重复模式

htrmnn0y  于 2023-02-02  发布在  Java
关注(0)|答案(5)|浏览(150)

如何在字符串中找到重复的模式?例如,如果输入文件

AAAAAAAAA
ABABAB
ABCAB
ABAb

它将输出:

A
AB
ABCAB
ABAb
brtdzjyr

brtdzjyr1#

如果使用regex,则只需要一行:

String repeated = str.replaceAll("(.+?)\\1+", "$1");

分解正则表达式(.+?)\1

  • (.+?)表示“至少一个字符,但尽可能少,作为组1捕获”
  • \1表示“与组1相同的字符

下面是一些测试代码:

String[] strs = {"AAAAAAAAA", "ABABAB", "ABCAB", "ABAb"};
for (String str : strs) {
    String repeated = str.replaceAll("(.+?)\\1+", "$1");
    System.out.println(repeated);
}

输出:

A
AB
ABCAB
ABAb
hzbexzde

hzbexzde2#

这个输出你所要求的-正则表达式可能可以改进,以避免循环,但我不能设法修复它...

public static void main(String[] args) {
    List<String> inputs = Arrays.asList("AAAAAAAAA", "ABABAB", "ABCAB", "ABAb");
    for (String s : inputs) System.out.println(findPattern(s));
}

private static String findPattern(String s) {
    String output = s;
    String temp;
    while (true) {
        temp = output.replaceAll("(.+)\\1", "$1");
        if (temp.equals(output)) break;
        output = temp;
    }
    return output;
}
z0qdvdin

z0qdvdin3#

用C#编写,但翻译应该是微不足道的。

public static string FindPattern(string s)
{
    for (int length = 1; length <= s.Length / 2; length++)
    {
        string pattern = s.Substring(0, length);
        if(MatchesPattern(s, pattern))
        {
            return pattern;
        }
    }
    return s;
}

public static bool MatchesPattern(string s, string pattern)
{
    for (int i = 0; i < s.Length; i++)
    {
        if(!s[i].Equals(pattern[i%pattern.Length]))
        {
            return false;
        }
    }
    return true;
}
68bkxrlz

68bkxrlz4#

如果重复段之间可能有空格:

(.+?)(\\ ?\\1)+
oug3syen

oug3syen5#

你不需要reexp就可以找到模式,Knuth-Morris-Pratt KMP算法可以更快地找到模式。

func getPattern(s string) string {
   res := make([]int, len(s)+1)

   i := 0
   j := -1
   res[0] = -1

   var patternLength int
   for i < len(s) {
       if j == -1 || s[i] == s[j] {
           i++
           j++
           res[i] = j
           if res[i] == 0 {
               patternLength++
           } else {
               break
           }
       } else {
           j = res[j]
       }
   }
   if patternLength == len(s) {
       patternLength = 0
   }
   return s[:patternLength]
}

单元测试

func Test_getPattern(t *testing.T) {
    testCases := []struct {
        str1     string
        expected string
    }{
        {"AAAAAAAAA", "A"},
        {"ABCABC", "ABC"},
        {"ABABAB", "AB"},
        {"LEET", ""},
    }

    for _, tc := range testCases {
        actual := getPattern(tc.str1)
        if tc.expected != actual {
            t.Errorf("Source: s1:%s\n   Expected:%s\n   Actual:  %s",
                tc.str1,
                tc.expected,
                actual)
        }
    }
}

相关问题