繁体   English   中英

如何使用变量和标记实现马尔可夫算法?

[英]How can I implement Markov's algorithm with variables and markers?

我一直在尝试实现马尔可夫算法,但仅获得了部分成功。 该算法非常简单,可以在此处找到。

但是,我的项目有一个额外的困难,我必须使用包含标记和变量的规则。

变量代表字母中的任何字母,标记只是一个字符,用作将变量四处移动的参考(它没有实数值)。

此示例复制字符串中的每个字符:

字母:{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

这是我的递归函数,实现了markov算法,该算法仅适用于字符串输入,例如:规则1:“苹果”->“橙色”,输入:“苹果”。

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准则,请在评论中告诉我原因,以免重复错误。

谢谢!

GitHub上

我认为最简单的方法是使用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的代码中有一些重复,因此您可以将它第一次粘贴在temp变量中replaceFirst用它:

String next = input.replace(rule.getFrom(), rule.getTo());
if (!input.equals(next)) {
  ...
  input = next;
  ...
}

当您当前引用整个rule.getFrom()字符串时,我想您以前在使用正则表达式特殊字符时遇到了问题。 如果是这样,则在创建规则时需要分别解决它们。 我真的不想在这里进入正则表达式,因为它是一个很大的领域,并且与Markov算法完全分开,所以如果您对此有疑问,请在线进行一些研究(例如, 正则表达式捕获组 ),或在此处针对正则表达式特定的问题提出一个单独的问题。

请注意,您仍然可以将这些规则与常规规则结合使用(将标记字符从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..

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM