【问题标题】:detect incomplete patterns in strings检测字符串中的不完整模式
【发布时间】:2014-02-13 17:36:13
【问题描述】:

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

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);
    }
}

【问题讨论】:

    标签: java regex string prediction


    【解决方案1】:

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

    1234 = 2
    1344 = 1
    4411 = 5
    

    但如果不是,那么你必须修改Longest Repeated Substring 算法。由于您需要所有重复的子字符串,因此请跟踪所有子字符串,而不仅仅是最长的子字符串。此外,您必须检查子字符串的最小长度以及重叠子字符串。 google 一下,你会发现很多关于这个算法的参考资料。

    【讨论】:

    • 我在我的问题中添加了算法的修改版本,感谢提示!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-04
      • 2017-05-13
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多