【问题标题】:Detecting type of operator stored as string in java [duplicate]检测在java中存储为字符串的运算符类型[重复]
【发布时间】:2015-11-16 04:40:08
【问题描述】:

在 Java 程序中,我有这些字符串:

a= 8,7,"+"
b=1,5,"*"

每一行都是一个单独的进程。我希望在每一行中,使用该运算符计算出的两个数字。但我不想使用任何类型的条件系统来检测每一行中的操作员。

其实我的主要问题是无条件检测运算符的类型。我不想使用 Javascript 引擎。我想知道有没有有效和标准的方法。

【问题讨论】:

  • 你不能在 Java 中编写这样的字符串。你能以正确的方式格式化字符串吗?
  • Enum.valueOf() 将是标准技术,或地图查找,或开关,但他们是否避免你的条件恐惧症只有你可以说。如果您有某种 实际 约束,请说明。您是否正在寻找标准的 RPN 评估器?它们很容易编写,但在您指定任意约束时则不然。
  • 这样的人为限制听起来非常像家庭作业。

标签: java jakarta-ee


【解决方案1】:

您可以将后缀表达式转换为中缀数学表达式,并使用 Java 或 javascript 中的表达式求值器执行它(不是首选)。正如您推荐 java,以下链接将对您有所帮助:

evaluating-a-math-expression-given-in-string-form

java-parse-a-mathematical-expression-given-as-a-string-and-return-a-number

从以上两个链接回答:

您可以将它传递给 BeanShell bsh.Interpreter,如下所示:

Interpreter interpreter = new Interpreter(); 
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));

如果您的问题得到解决,请告诉我们。

【讨论】:

  • OP 已经排除了 JavaScript。这两个链接都是关于中缀符号的。这个问题是关于 RPN 的。
  • 只有将后缀表达式转换为中缀时,该解决方案才有效。我应该明确提到它。我会更新的。
  • 那完全没有意义。 RPN 中的表达式已经采用适合直接评估的形式。您的两个链接都将中缀表达式转换为 RPN,然后对其进行评估。您不能认真地建议在其前面放置一个 RPN->中缀转换。
  • 如果你只看问题的表达,也许你是对的。但也有限制。这里提到的约束是“不使用条件”。标准的数学中缀表达式可以很容易地在约束下进行评估。除此之外,表达式不是标准的后缀表示法。为了处理它,用户需要重新发明轮子并编写代码来处理这样的表达式。在我看来,这是额外的开销。
  • 您的两个链接都包含无穷无尽的条件。坦率地说,将 RPN 转换为中缀并返回 RPN 的建议是荒谬的。你还没有告诉他怎么做。除了逗号和(可能是错误的)引号之外,这些表达式确实是标准的后缀表示法,它们都不需要中缀解析算法来处理它们。
【解决方案2】:

首先拆分字符串并将运算符存储在 Character 变量中。您可以使用split() 拆分字符串并将其分配给字符串数组。使用数组索引访问运算符并将其分配给 Character 变量。

现在您可以使用Map<Character,Object>,您可以在其中存储字符和对象以在单个结构中进行计算,稍后仅使用字符访问,而无需任何if-elseswitch

Map<Character,Object> map = new HashMap<>();
map.put('+', plusObject);
map.put('-', minusObject);
map.put('*', multiplyObject);
map.put('/', divideObject);

要获取运算符的对象类型,可以使用map.get(character),它将根据字符返回对象,否则返回null。

更新:为每个类创建四个类和一个对象,即plusObjectminusObjectmultiplyObjectdivideObject。这些是您最初添加到HashMap 的对象。每个班级都有一个evaluate() 函数。现在使用返回的对象,调用evaluate() 方法,该方法将调用相应的类。您无需使用任何条件语句检查 Object 类型。

【讨论】:

  • 我的主要问题是您的语句“现在基于返回的对象......”的结尾。检查返回的对象,需要条件语句,我不能使用条件
  • 哦,是的。如果我有任何其他想法,我会尽快查看并更新。
  • @Fcoder 你收到更新了吗?
【解决方案3】:

J. Selva 回复的另一个解决方案:

改进

  1. 单课
  2. 静态块
  3. 更好的抽象

导入 java.util.HashMap; 导入 java.util.Map;

/**
 * Created by SEA-HAWK on 23/8/15.
 */
public abstract class Expr {
    public static Map<String,Object> op;
    static{
        op=new HashMap<>();
        op.put("+", new Expr() {
            @Override
            public int evaluate(int a, int b) {
                return a + b;
            }
        });
        op.put("-", new Expr() {
            @Override
            public int evaluate(int a, int b) {
                return a - b;
            }
        });
        op.put("*", new Expr() {
            @Override
            public int evaluate(int a, int b) {
                return a * b;
            }
        });

        op.put("/", new Expr() {
            @Override
            public int evaluate(int a, int b) {
                return a / b; // decimal point loss
            }
        });
    }
    abstract public int evaluate(int a, int b);
    public static int exprEval(String expr){
        String a[]=expr.split(",");
        a[2]=a[2].replaceAll("\"","");
        return ((Expr)op.get(a[2])).evaluate(Integer.parseInt(a[0]),Integer.parseInt(a[1]));
    }
}

主要功能:

public static void main(String[] args) {
    String x="20,10,\"*\"";
    System.out.println(x+"="+Expr.exprEval(x));
     x="20,10,\"+\"";
    System.out.println(x+"="+Expr.exprEval(x));
     x="20,10,\"-\"";
    System.out.println(x+"="+Expr.exprEval(x));
    x="20,10,\"/\"";
    System.out.println(x+"="+Expr.exprEval(x));
}

输出:

20,10,"*"=200
20,10,"+"=30
20,10,"-"=10
20,10,"/"=2

注意:更改浮点/十进制值计算的数据类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多