【问题标题】:Boolean formula布尔公式
【发布时间】:2018-11-25 10:17:08
【问题描述】:

给定一个任意的 2 值布尔代数公式,例如 (1V0)∧1V~(0∧1)。如何使用 JavaScript 得到这个公式的结果?我的意思是,老师给出了一个公式,我的程序应该打印结果 1 或 0。

【问题讨论】:

  • 这与javascript无关,我也和其他语言一样。尝试用 javascript 中的等效逻辑运算符替换每个逻辑运算符。 1 和 0 也可能是字符串的形式,所以我会用 truefalse 替换它们。
  • 我认为OP的意思是程序应该充当解释器并采用该公式的文本形式,并返回答案。但这只是我的猜测。

标签: javascript boolean


【解决方案1】:

我想这个练习的目的是学习解析和形式语法的基础知识。以下是一些帮助您入门的信息。

首先,您将输入拆分为“标记”或符号(运算符、值、括号)。这称为“词法分析”,在您的情况下相当简单,因为您的符号始终是一个字符。

然后,您从这些标记构建解析树或“AST”。解析树中的每个节点都是一个对象operator left right,其中leftright 可以是值或其他节点对象。例如,

a v b ^ c

产生以下解析树

   operator = v
   left = a
   right = {
       operator = ^
       left = b
       right = c
   }

要构建解析器,您需要为表达式定义一组正式规则,称为“语法”。布尔值的示例语法:

 <b-expression>::= <b-term> [OR <b-term>]*
 <b-term>      ::= <not-factor> [AND <not-factor>]*
 <not-factor>  ::= [NOT] <b-factor>
 <b-factor>    ::= <b-literal> | <b-variable> | (<b-expression>)

(https://compilers.iecc.com/crenshaw/tutor6.txt)

构建 AST 后,您可以使用简单的递归算法“评估”每个树节​​点:

evaluate(node)
   if node is a value (e.g. "1"), return this value
   otherwise, 
        L = evaluate(node.left)
        R = evaluate(node.right)
        V = apply node.operator to L and R
        return V

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    你可以使用逻辑运算符,比如

    并替换给定的布尔运算符。

     console.log((1 || 0) &amp;&amp; 1 || !(0 &amp;&amp; 1));

    【讨论】:

      【解决方案3】:

      如果输入总是值得信赖的,一种选择是将表达式转换为正确的 JS 语法,然后使用eval

      const check = str => Boolean(eval(str
        .replace(/v/gi, '||')
        .replace(/∧/g, '&&')
        .replace(/~/g, '!')
      ));
      
      console.log(check('(1V0)∧1V~(0∧1)'));
      console.log(check('0∧0'));
      console.log(check('1∧1'));
      console.log(check('1∧0'));
      console.log(check('1V0'));
      console.log(check('0V0'));

      【讨论】:

      • 好吧,我猜这是来自编译器类,我不认为“使用编译器”是“如何编写编译器”问题的正确答案。就像对驾校学生说“打车”一样。 ;)
      猜你喜欢
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      相关资源
      最近更新 更多