Java 如何实现Markov';带变量和标记的s算法?
我一直在尝试实现马尔可夫算法,但只取得了部分成功。算法相当简单,可以找到 然而,我的项目还有一个额外的困难,我必须使用包含标记和变量的规则 变量表示字母表中的任何字母,标记只是一个字符,用作移动变量的参考(它没有实际值) 此示例复制字符串中的每个字符: 字母表:{a,b,c} 标记:{M} 变量:{x} 规则1:Mx->xxM 规则2:xM->x 规则3:x->Mx 输入:abc abc//我们适用规则3 Mabc//我们适用规则1 aaMbc//我们适用规则1 aabbMc//我们适用规则1 aabbccM//我们适用规则2 aabbcc 这是我的递归函数,它实现了一个马尔可夫算法,只适用于字符串输入,例如:规则1:“苹果”->“橙色”,输入:“苹果”Java 如何实现Markov';带变量和标记的s算法?,java,recursion,replace,cycle,markov,Java,Recursion,Replace,Cycle,Markov,我一直在尝试实现马尔可夫算法,但只取得了部分成功。算法相当简单,可以找到 然而,我的项目还有一个额外的困难,我必须使用包含标记和变量的规则 变量表示字母表中的任何字母,标记只是一个字符,用作移动变量的参考(它没有实际值) 此示例复制字符串中的每个字符: 字母表:{a,b,c} 标记:{M} 变量:{x} 规则1:Mx->xxM 规则2:xM->x 规则3:x->Mx 输入:abc abc//我们适用规则3 Mabc//我们适用规则1 aaMbc//我们适用规则1 aabbMc//我们适用规则1
公共静态字符串(字符串输入,LinkedList规则){
for(规则:规则){
if(!input.equals(input.replace(rule.getFrom(),rule.getTo())){//如果规则与子字符串匹配
if(rule.isTerminating()){//如果规则正在终止
input=input.replaceFirst(Pattern.quote(rule.getFrom()),rule.getTo());
System.out.println(输入);//替换第一个实例
返回输入;//返回并结束循环
}否则{
input=input.replaceFirst(Pattern.quote(rule.getFrom()),rule.getTo());
系统输出打印项次(输入);
返回markov(输入,规则);//再次开始查找匹配的规则
}
}
}
返回输入;
}
我不知道如何在这个逻辑中实现变量和标记,所以也许有人可以教我实现这个逻辑的最佳方法?欢迎任何建议
如果问题不符合SO指南,请在评论中告诉我原因,这样我就不会重复错误
谢谢大家!
我认为最简单的方法是使用Java正则表达式。一旦你了解了这些,那么以下规则应该适用于你的例子:
Rule 1: "M([a-c])" -> "$1$1M"
Rule 2: "([a-c])M" -> "$1" (terminating)
Rule 3: "([a-c])" -> "M$1"
请注意,您需要对当前方法进行一些调整才能使其正常工作
replace
将文本字符串作为第一个参数,而replaceFirst
使用正则表达式,因此:
replace: if (!input.equals(input.replace(rule.getFrom(), rule.getTo()))) {
with: if (!input.equals(input.replaceFirst(rule.getFrom(), rule.getTo()))) {
您引用的是规则.getFrom()
字符串,该字符串不适用于正则表达式,因此:
replace: input = input.replaceFirst(Pattern.quote(rule.getFrom()), rule.getTo());
with: input = input.replaceFirst(rule.getFrom(), rule.getTo());
此时,调用两次replaceFirst
的代码中有一点重复,因此您可以在第一次将其粘贴到temp变量中并重用它:
String next = input.replace(rule.getFrom(), rule.getTo());
if (!input.equals(next)) {
...
input = next;
...
}
由于您当前引用了整个规则.getFrom()
字符串,我猜您以前在正则表达式特殊字符方面遇到过问题。如果是这样,您需要在创建规则时单独解决这些问题。我真的不想在这里讨论正则表达式,因为它是一个巨大的领域,并且完全独立于马尔可夫算法,因此如果您在这些方面有问题,请在线进行一些研究(例如and),或者在这里提出一个单独的问题,重点关注正则表达式特定的问题
请注意,您仍然可以将这些规则与常规规则相结合(将标记字符从M
更改为#
以允许在字母表中使用M
),这些规则:
"A" -> "apple"
"B" -> "bag"
"S" -> "shop"
"T" -> "the"
"the shop" -> "my brother"
"#([a-zA-Z .])" -> "$1$1#"
"([a-zA-Z .])#" -> "$1" (terminating)
"([a-zA-Z .])" -> "#$1"
将转换为:
from: I bought a B of As from T S.
to: II bboouugghhtt aa bbaagg ooff aapppplleess ffrroomm mmyy bbrrootthheerr..
希望这有帮助。我认为最简单的方法是使用Java正则表达式。一旦你了解了这些,那么以下规则应该适用于你的例子:
Rule 1: "M([a-c])" -> "$1$1M"
Rule 2: "([a-c])M" -> "$1" (terminating)
Rule 3: "([a-c])" -> "M$1"
请注意,您需要对当前方法进行一些调整才能使其正常工作
replace
将文本字符串作为第一个参数,而replaceFirst
使用正则表达式,因此:
replace: if (!input.equals(input.replace(rule.getFrom(), rule.getTo()))) {
with: if (!input.equals(input.replaceFirst(rule.getFrom(), rule.getTo()))) {
您引用的是规则.getFrom()
字符串,该字符串不适用于正则表达式,因此:
replace: input = input.replaceFirst(Pattern.quote(rule.getFrom()), rule.getTo());
with: input = input.replaceFirst(rule.getFrom(), rule.getTo());
此时,调用两次replaceFirst
的代码中有一点重复,因此您可以在第一次将其粘贴到temp变量中并重用它:
String next = input.replace(rule.getFrom(), rule.getTo());
if (!input.equals(next)) {
...
input = next;
...
}
由于您当前引用了整个规则.getFrom()
字符串,我猜您以前在正则表达式特殊字符方面遇到过问题。如果是这样,您需要在创建规则时单独解决这些问题。我真的不想在这里讨论正则表达式,因为它是一个巨大的领域,并且完全独立于马尔可夫算法,因此如果您在这些方面有问题,请在线进行一些研究(例如and),或者在这里提出一个单独的问题,重点关注正则表达式特定的问题
请注意,您仍然可以将这些规则与常规规则相结合(将标记字符从M
更改为#
以允许在字母表中使用M
),这些规则:
"A" -> "apple"
"B" -> "bag"
"S" -> "shop"
"T" -> "the"
"the shop" -> "my brother"
"#([a-zA-Z .])" -> "$1$1#"
"([a-zA-Z .])#" -> "$1" (terminating)
"([a-zA-Z .])" -> "#$1"
将转换为:
from: I bought a B of As from T S.
to: II bboouugghhtt aa bbaagg ooff aapppplleess ffrroomm mmyy bbrrootthheerr..
希望这有帮助