skip to Main Content

I have been searching around but did not find any good solution yet, so what I am trying to do is I have below input Strings

(a&b|c)&d
a&(b|c)
(a&b)|(c&d)

so basically I want to validate if the input String is a valid logical expression, and below inputs should return false;

a(b&c)
a(&b|c)
(a&b

So wonder is there a standard way to do this?

I tried this code
https://www.interviewkickstart.com/problems/valid-parentheses
but this do not cover all cases
(a(&b&c)) will fail

2

Answers


  1. Chosen as BEST ANSWER

    So I actually write some code like this

    class Validator {
        #currentIndex;
        #expression;
        validate(expression) {
            this.#currentIndex = 0;
            this.#expression = expression;
            return this.#is_valid(false);
        }
        #is_valid(expectEndParenthese) {
    
            var preIsStartingOrOperator = true;
            while (this.#currentIndex < this.#expression.length) {
    
                const currentCharacter = this.#expression[this.#currentIndex];
                debugger;
                // variable or (...) can eventually evulated to true or False, so let's call it Evaluatable, so it can only be pre by an operator or starting
                if (this.#isDigit(currentCharacter) || currentCharacter === '(') {
                    if (!preIsStartingOrOperator) {
                        return false;
                    }
                    preIsStartingOrOperator = false;
                    if (currentCharacter === '(') {
                        this.#currentIndex++;
                        if (!this.#is_valid(true)) {
                            return false;
                        } else {
                            this.#currentIndex++;
                        }
                    } else {
                        this.#currentIndex++;
                    }
                } else if (this.#isOperator(currentCharacter)) {
                    // operators can not be at the start of the expression or after another operator
                    if (preIsStartingOrOperator) {
                        return false;
                    }
                    preIsStartingOrOperator = true;
                    this.#currentIndex++;
                } else {
                    // close parenthese can only after Evaluatable and there must be a start parenthese.
                    return !preIsStartingOrOperator && expectEndParenthese;
                }
            }
            return !expectEndParenthese;
        }
        /*checks if the given character is a digit.*/
        #isDigit(c) {
            if (c >= '0' && c <= '9') {
                return true;
            }
            return false;
        }
    
        #isOperator(c) {
            if (c === '&' || c === '|') {
                return true;
            }
            return false;
        }
    }
    
    const validator = new Validator();
    console.log(validator.validate("1&(2|(5|6|(7|0|8))&4)&3"));
    
    

    which can do validtion, so my ideal here is I treat both digit and left parenthese as Evaluatable which should be eventually evaluated to true or false, and this Evaluatable can only be added at beginning or after an operator, for operator, it can only be added after a Value, and for each is_valid recursive, we need know if it expectEndparentheses or not


  2. Try this one

    function isValidLogicalExpression(expression) {
      let index = 0;
    
      function isOperand(char) {
        return /[a-z]/i.test(char);
      }
    
      function isOperator(char) {
        return /[&|]/.test(char);
      }
    
      function parseExpression() {
        let isValid = parseTerm();
    
        while (index < expression.length && isOperator(expression[index])) {
          index++; // Move past the operator
          isValid = parseTerm();
        }
    
        return isValid;
      }
    
      function parseTerm() {
        if (isOperand(expression[index])) {
          index++; // Move past the operand
          return true;
        } else if (expression[index] === '(') {
          index++; // Move past '('
          const isValid = parseExpression();
          if (expression[index] === ')') {
            index++; // Move past ')'
            return isValid;
          } else {
            return false; // Missing closing parenthesis
          }
        } else {
          return false; // Invalid character
        }
      }
    
      return parseExpression() && index === expression.length;
    }
    
    // Test cases
    console.log(isValidLogicalExpression("(a&b|c)&d")); // true
    console.log(isValidLogicalExpression("a&(b|c)"));    // true
    console.log(isValidLogicalExpression("(a&b)|(c&d)")); // true
    
    console.log(isValidLogicalExpression("a(b&c)"));      // false
    console.log(isValidLogicalExpression("a(&b|c)"));     // false
    console.log(isValidLogicalExpression("(a&b"));        // false
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search