我一直在努力实现马尔可夫的算法,但我只取得了部分成功。该算法非常简单,可以找到here。
但是,我的项目有一个额外的难度,我必须使用包含标记和变量的规则。
变量表示字母表中的任何字母,而标记只是一个字符,用作移动变量的参考(它没有实际值)。
此示例复制字符串中的每个字符:
字母:{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:“apple” - > “橙色”,输入:“apple”。
public static String markov(String input, LinkedList<Rule> rules) {
for (Rule rule : rules) {
if (!input.equals(input.replace(rule.getFrom(), rule.getTo()))) { //If the rule matches a substring
if (rule.isTerminating()) { //If the rule is terminating
input = input.replaceFirst(Pattern.quote(rule.getFrom()), rule.getTo());
System.out.println(input); //Replace the first instance
return input; //return and end the cycle
} else {
input = input.replaceFirst(Pattern.quote(rule.getFrom()), rule.getTo());
System.out.println(input);
return markov(input, rules); //Start looking again for matching rules
}
}
}
return input;
}
我无法弄清楚如何在这个逻辑中实现变量和标记,所以也许有人可以教会我实现这个逻辑的最佳方法?欢迎任何建议。
如果问题不符合SO指南,请在评论中告诉我,为什么我不重复这个错误。
谢谢!
答案 0 :(得分:0)
我认为最简单的方法是使用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()))) {
您引用的rule.getFrom()
字符串不适用于正则表达式,因此:
replace: input = input.replaceFirst(Pattern.quote(rule.getFrom()), rule.getTo());
with: input = input.replaceFirst(rule.getFrom(), rule.getTo());
此时,您在调用replaceFirst
两次的代码中有一些重复,因此您可以在第一次将其粘贴到临时变量中并重复使用它:
String next = input.replace(rule.getFrom(), rule.getTo());
if (!input.equals(next)) {
...
input = next;
...
}
当你正在引用整个rule.getFrom()
字符串时,我猜你之前遇到过正则表达式特殊字符的问题。如果是这样,您将需要在创建规则时单独解决它们。我真的不想进入正则表达式,因为它是一个巨大的区域,并且完全独立于马尔可夫算法,所以如果您遇到这些问题,请在线进行一些研究(例如Regular Expressions和{ {3}}),或在这里提出一个单独的问题,重点关注正则表达式特定问题。
请注意,您仍然可以将这些与常规规则结合使用(将标记字符从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..
希望这有帮助。