检测字符串中不完整的模式

时间:2014-02-13 17:36:14

标签: java regex string prediction

我有一个包含嵌套重复模式的字符串,例如:

String pattern1 = "1234";
String pattern2 = "5678";
String patternscombined = "1234|1234|5678|9"//added | for reading pleasure
String pattern = (pattern1 + pattern1 + pattern2 + "9")
                +(pattern1 + pattern1 + pattern2 + "9")
                +(pattern1 + pattern1 + pattern2 + "9")
String result = "1234|1234|5678|9|1234|1234|56";

正如您在上面的示例中所看到的,结果被切断了。但是当了解重复模式时,您可以预测接下来会发生什么。

现在问我的问题: 如何预测此模式的下一次重复,以获得如下结果字符串:

String predictedresult = "1234|1234|5678|9|1234|1234|5678|9|1234|1234|5678|9";

模式将小于10个字符,预测结果将小于1000个字符。

我只收到截止结果字符串,模式识别程序已经实现并正常工作。在上面的示例中,我将resultpattern1pattern2patternscombined

编辑:

我找到了一个适合我的解决方案:

import java.util.Arrays;


public class LRS {
    // return the longest common prefix of s and t
    public static String lcp(String s, String t) {
        int n = Math.min(s.length(), t.length());
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) != t.charAt(i))
                return s.substring(0, i);
        }
        return s.substring(0, n);
    }

    // return the longest repeated string in s
    public static String lrs(String s) {
        // form the N suffixes
        int N = s.length();
        String[] suffixes = new String[N];
        for (int i = 0; i < N; i++) {
            suffixes[i] = s.substring(i, N);
        }
        // sort them
        Arrays.sort(suffixes);
        // find longest repeated substring by comparing adjacent sorted suffixes
        String lrs = "";
        for (int i = 0; i < N - 1; i++) {
            String x = lcp(suffixes[i], suffixes[i + 1]);
            if (x.length() > lrs.length())
                lrs = x;
        }
        return lrs;
    }

    public static int startingRepeats(final String haystack, final String needle)
    {
        String s = haystack;
        final int len = needle.length();
        if(len == 0){
            return 0;
        }
        int count = 0;

        while (s.startsWith(needle)) {
            count++;
            s = s.substring(len);
        }

        return count;
    }

    public static String lrscutoff(String s){
        String lrs = s;
        int length = s.length();
        for (int i = length; i > 0; i--) {
            String x = lrs(s.substring(0, i));
            if (startingRepeats(s, x) < 10 &&
                    startingRepeats(s, x) > startingRepeats(s, lrs)){
                lrs = x;
            }
        }
        return lrs;
    }

    // read in text, replacing all consecutive whitespace with a single space
    // then compute longest repeated substring
    public static void main(String[] args) {
        long time = System.nanoTime();
        long timemilis = System.currentTimeMillis();
        String s = "12341234567891234123456789123412345";
        String repeat = s;
        while(repeat.length() > 0){
            System.out.println("-------------------------");
            String repeat2 = lrscutoff(repeat);
            System.out.println("'" + repeat + "'");

            int count = startingRepeats(repeat, repeat2);
            String rest = repeat.substring(count*repeat2.length());
            System.out.println("predicted: (rest ='" + rest + "')" );
            while(count > 0){
                System.out.print("'" + repeat2 + "' + ");
                count--;
            }
            if(repeat.equals(repeat2)){
                System.out.println("''");
                break;
            }
            if(rest!="" && repeat2.contains(rest)){
                System.out.println("'" + repeat2 + "'");
            }else{
                System.out.println("'" + rest + "'");
            }

            repeat = repeat2;

        }
        System.out.println("Time: (nano+millis):");
        System.out.println(System.nanoTime()-time);
        System.out.println(System.currentTimeMillis()-timemilis);
    }
}

2 个答案:

答案 0 :(得分:1)

您似乎需要像n-gram language model这样的东西,这是一个基于共同发生事件计数的统计模型。如果您获得了一些训练数据,您可以从看到的模式计数中推导出概率。如果没有,您可以尝试手动指定它们,但这可能会变得棘手。一旦你有这样一种语言模型(数字模式对应于单词),你总是可以通过选择一个具有最高概率的单词模式来预测下一个单词(“历史”)。

答案 1 :(得分:1)

如果您的预测字符串始终是管道(|)数字,那么您可以使用管道轻松拆分它们,然后跟踪HashMap上的计数。例如

1234 = 2
1344 = 1
4411 = 5

但如果没有,那么你必须修改Longest Repeated Substring算法。因为你需要有所有重复的子串,所以跟踪所有,而不是只有最长的。此外,您必须检查子串的最小长度以及重叠的子串。通过搜索谷歌,你会发现很多这个算法的参考。