0

我正在做的是以有限字母字符串的形式制定生产规则,将其复制到 char 数组中,然后通过 if 语句运行它,该语句根据字符调用函数。

如“lff[f]”调用functionL、functionF、functionF、functionOpenB、functionF、functionCloseB。

所以目前它的:

workRuleArr= stringProdrule.toCharArray();
for  (char c=0; c < workRuleArr.length; c++){
    if (workRuleArr[c] == 'f')
     {
          functionF();

      }
      if (workRuleArr[c] == 'l')
     {
          functionL();

      }

ETC

这很好并且可以工作,但是:

我如何将参数从生产规则传递给那些函数,例如“l(100)ff ..”,以便它调用functionL(x)......其中x = 100并将100传递给函数?

并且在同一个生产规则字符串中可能有许多不同的 x 值。用户在程序开始时一次性输入规则,因此需要在同一生产规则中处理多个参数

如果问题不清楚,请告诉我任何想法。谢谢

4

5 回答 5

4

Seems to me that those "rule functions" you have all serve a similar purpose, so they obey the same interface, like

interface Rule{
    void executeRule();
}

Then you have different Rules that implement that interface, like

class RuleF implements Rule{
        void executeRule(){
            //execute rule F
        }
}

class RuleL implements Rule{
        void executeRule(){
            //execute rule L
        }
}

Then you need a simple way to associate a character with a given rule. Use a HashMap, like:

Map<Character, Rule> ruleMap = new HashMap<Character, Rule>();
ruleMap.add('f', new RuleF());
ruleMap.add('l', new RuleL());

With that you can remove all those "ifs", like

workRuleArr= stringProdrule.toCharArray();
for  (char c=0; c < workRuleArr.length; c++){
    Rule rule = ruleMap.get(workRuleArr[c]);
    rule.executeRule();
}

Now if you need that the Rule interface receives a parameter, you'll also need a similar Map object to associate the character with the parameter you need to pass.

What exactly are you building? Some sort of state machine?

cheers, good luck! :-)

于 2012-04-29T20:53:37.113 回答
1

看看命令模式。你基本上是在问这个问题的答案

于 2012-04-29T21:09:22.217 回答
1

看起来您需要某种可以为您提供有效令牌的解析器,或者需要自己组装。无论如何,您都需要在阵列中向前看一步。这是另一个实现:

String rule = "FLL(123)FKF";

String pattern = "[a-zA-Z]{1}|[(\\d)]+"; //any single character or set of (numbers)
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(rule);

String command = "", param = "", token;

while(m.find()){
  token = m.group();

  if(token.length() > 1){  //must be parameter
    param = token.substring(1, token.length()-1);
    continue;
  }

  if(command != ""){
    runCommand(command, param);
    param = "";  //clear
  }
  command = token;  //set next
}

if(command != "")    //last trailing run
  runCommand(command, param);  

还需要定义runCommand:

bool runCommand(string command, string param){
  System.out.println("execute function" + command + "(" + param + ")");

  bool success, hasParam = (param != "");
  int p = Integer.parseInt(param);

  switch(command){
    case "F":
      success = (hasParam ? functionF() : functionF(p));
      break;
    case "L":
      success = (hasParam ? functionL() : functionL(p));
      break;
    case "K":
      success = (hasParam ? functionK() : functionK(p));
      break;
  }
  return success;
}
于 2012-04-29T23:05:57.720 回答
0

尝试一个简单的 if 语句来测试是否有参数:

workRuleArr= stringProdrule.toCharArray();

for  (char c=0; c < workRuleArr.length; c++){

    if (workRuleArr[c] == 'f') {

        if(workRuleArr[c+1].equals("(")) {

            // use the parameter
            String param = "";

            c++;

            while(!workRuleArr[c+1].equals(")")) {
                param += workRuleArr[c+1];
                c++;
            }

            int yourParameter = Integer.parseInt(param);

            functionF(yourParameter);
        }
        else {

            functionF();
        }
    }
    if (workRuleArr[c] == 'l'){

        functionL();
    }
}

请注意,我没有测试代码,可能会有一些错误。

于 2012-04-29T20:46:50.520 回答
0

我不会转换成 char 数组,因为 String 有更多有用的方法,在这种情况下也是如此。 

因此,对于每个具有索引的字符,i您需要测试字符 ati+1是否为 '(',然后用于int k = stringProdrule.indexOf(')', i+2)获取右括号并将两个括号之间的字符串作为参数传递给函数。然后继续 at k+1。 

于 2012-04-29T20:58:47.437 回答