Java 检测字符串中的不完整模式
我有一个包含嵌套重复模式的字符串,例如:Java 检测字符串中的不完整模式,java,regex,string,prediction,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 + patter
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个字符
我只收到截断结果字符串,模式识别程序已经实现并开始工作。在上面的例子中,我将把result
、pattern1
、pattern2
和patternscombined
编辑:
我找到了一个适合我的解决方案:
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.util.array;
公共级LRS{
//返回s和t的最长公共前缀
公共静态字符串lcp(字符串s、字符串t){
int n=Math.min(s.length(),t.length());
对于(int i=0;ilrs.length())
lrs=x;
}
返回lrs;
}
公共静态整数启动重复(最终字符串草垛、最终字符串针)
{
字符串s=干草堆;
最终整数长度=针的长度();
如果(len==0){
返回0;
}
整数计数=0;
而(s.startsWith(针)){
计数++;
s=s.子串(len);
}
返回计数;
}
公共静态字符串LRSCUTOF(字符串s){
字符串lrs=s;
int length=s.length();
对于(int i=长度;i>0;i--){
字符串x=lrs(s.子字符串(0,i));
如果(启动)重复(s,x)<10&&
启动重复(s,x)>启动重复(s,lrs)){
lrs=x;
}
}
返回lrs;
}
//读入文本,用单个空格替换所有连续的空白
//然后计算最长的重复子串
公共静态void main(字符串[]args){
长时间=System.nanoTime();
long-timemilis=System.currentTimemilis();
字符串s=“12341234567891234123456789123412345”;
字符串重复=s;
while(repeat.length()>0){
System.out.println(“---------------------------”);
字符串重复2=LRSCUTOF(重复);
System.out.println(“'”+repeat+“”);
int count=开始重复(重复,重复2);
字符串rest=repeat.substring(count*repeat2.length());
System.out.println(“预测:(rest='“+rest+”)”;
而(计数>0){
System.out.print(“'”+repeat2+“+”);
计数--;
}
if(重复等于(重复2)){
系统输出打印项次(“”);
打破
}
if(rest!=“”&&repeat2.contains(rest)){
System.out.println(“'”+repeat2+“”);
}否则{
System.out.println(“'”+rest+“”);
}
重复=重复2;
}
System.out.println(“时间:(纳米+毫秒):”;
System.out.println(System.nanoTime()-time);
System.out.println(System.currentTimeMillis()-timeMillis);
}
}
您似乎需要类似于的东西,这是一种基于共现事件计数的统计模型。如果给你一些训练数据,你可以从所见模式的计数中得出概率。如果没有,您可以尝试手动指定它们,但这可能会很棘手。一旦你有了这样一个语言模型(数字模式对应于单词),你总是可以通过选择一个概率最高的单词来预测下一个单词(“历史”)。如果你的预测字符串总是管道(|)然后,您可以使用管道轻松拆分这些数字,然后在HashMap
上跟踪计数。比如说
1234 = 2
1344 = 1
4411 = 5
但是如果不是,那么你必须修改算法。因为您需要所有重复的子字符串,所以要跟踪所有子字符串,而不是只跟踪最长的子字符串。此外,还必须检查子字符串的最小长度以及重叠的子字符串。通过搜索谷歌,你会发现很多关于这个算法的参考资料。我在问题中添加了我的算法修改版本,谢谢你的提示!