【问题标题】:Checking whether an expression is a valid formula检查表达式是否为有效公式
【发布时间】:2021-05-23 09:25:03
【问题描述】:

递归问题:一个公式被定义为一个字符串 包含正个位数、变量和操作 (例如:+、-、/、*、%)。另外,字符串不包含空格 酒吧。两个数字或变量之间的每个操作都是分开的 带括号 - “()”。

有效的公式是:((6+x)*(4+2)), (((9*4)+(x+8))*(6-5)), 6, (3+1) 等...

无效公式为:-6, (1+*(x+2)*(1-6)), ( (6+x)), 10, 2+x, (33+3), ((1+2)) 等等...

编写一个布尔递归函数,它得到一个字符串 - “s”和 如果他是一个有效的公式,则返回 true,否则返回 false。

  • 代码必须通过 java 编写。

我的尝试:我尝试了以下方法,但要记住“(”的数量小于“)”的数量,但是,它不正确,因为:“((1 + 2))”不是一个有效的公式。所以我写了以下内容:

 public static boolean isFormula(String s) {
        return calc(s, 0, 0, 0, 0);
    }

    public static boolean calc(String s, int oc, int l, int r, int g) {
        if (s == "") {
            return (oc <= 1 && (l == r));
        }
        char c = s.charAt(0);
        char e = s.charAt(s.length() - 1);
        if (g == 0) {
            if (!(op(s))) return false;
            else {
                return calc(s, oc, l, r, g + 1);
            }
        }
        if (c == '(') {
            return calc(s.substring(1), oc, l + 1, r, g);
        } else if (c == ')') {
            return calc(s.substring(1), oc, l, r + 1, g);
        } else if ((c >= '0' && c <= '9') || c == 'x') {
            if (oc <= 1) {
                return calc(s.substring(1), 0, l, r, g);
            }
        } else if ((c == '+' || c == '-' || c == '*' || c == '/')) {
            return calc(s.substring(1), oc + 1, l, r, g);
        }
        return false;
    }

    public static boolean op(String s) {
        int count = 0;
        if (s.charAt(0) == '+' || s.charAt(0) == '-' || s.charAt(0) == '*' || s.charAt(0) == '/') {
            count++;
        }
        String d = s.replace("(", "");
        if (d.charAt(0) == '+' || d.charAt(0) == '-' || d.charAt(0) == '*' || d.charAt(0) == '/') {
            count++;
        }
        d = d.replace(")", "");
        d = d.replace("+", ",");
        d = d.replace("-", ",");
        d = d.replace("*", ",");
        d = d.replace("/", ",");
        String[] words = d.split(",");
        int sum = words.length;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '/' || s.charAt(i) == '*') {
                count++;
            }
        }
        if (s.contains(" ")) return false;
        return (count <= sum - 1);
    }

想法: 我觉得这个问题很复杂,也不知道怎么排代码,因为我的方式好像不太对,而且很乱。我会很高兴得到一些帮助。为了写这篇文章,我付出了很多努力。谢谢!

【问题讨论】:

  • 您写道,表达式中的所有数字都必须是个位数。换句话说,只允许使用数字 0 到 9。那是对的吗?变量呢?我找不到关于变量的任何条件。从您的问题来看,唯一有效的变量似乎是x。对吗?
  • @Abra 你说的都对:)。

标签: java recursion


【解决方案1】:

试试这个。

static final Pattern DIGIT_OR_X = Pattern.compile("[\\dx]");
static final Pattern OPERATION = Pattern.compile("\\([\\dx][+*/%-][\\dx]\\)");

public static boolean isFormula(String s) {
    while (true) {
        if (DIGIT_OR_X.matcher(s).matches())
            return true;
        String rep = OPERATION.matcher(s).replaceAll("x");
        if (rep.equals(s))
            return false;
        s = rep;
    }
}

测试用例:

assertTrue(isFormula("((6+x)*(4+2))"));
assertTrue(isFormula("(((9*4)+(x+8))*(6-5))"));
assertTrue(isFormula("6"));
assertTrue(isFormula("(3+1)"));
assertFalse(isFormula("-6"));
assertFalse(isFormula("(1+*(x+2)*(1-6))"));
assertFalse(isFormula("( (6+x))"));
assertFalse(isFormula("10"));
assertFalse(isFormula("2+x"));
assertFalse(isFormula("(33+3)"));
assertFalse(isFormula("((1+2))"));

或者你也可以不用正则表达式。

static boolean isFormula(String s) {
    return new Object() {
        int index = 0;

        boolean match(String expects) {
            if (index >= s.length() || expects.indexOf(s.charAt(index)) < 0)
                return false;
            ++index;
            return true;
        }

        boolean formula() {
            if (match("0123456789x"))
                return true;
            return match("(")
                && formula() && match("+-*/%") && formula()
                && match(")");
        }

        boolean parse() {
            return formula() && index >= s.length();
        }
    }.parse();
}

【讨论】:

  • 首先,非常感谢!但是,当要求“isFormula”必须是递归时,我看不到递归在哪里。现在我看到使用递归的公式()不是吗?此评论属于第二种方法...
猜你喜欢
  • 2013-04-29
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多