patternjavaMinor
Boolean expressions from infix to postfix notation using Dijkstra's Shunting Yard algorithm
Viewed 0 times
yarddijkstrabooleanpostfixinfixexpressionsalgorithmnotationusingfrom
Problem
I began working on a Java library that receives a boolean expression such as
```
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Main {
/**
* The name of AND operator.
*/
public static final String AND = "and";
/**
* The name of NOT operator.
*/
public static final String NOT = "not";
/**
* The name of OR operator.
*/
public static final String OR = "or";
/**
* Exit command.
*/
public static final String QUIT = "quit";
/**
* The default operator precedence: NOT, AND, OR.
*/
private static final Map defaultPrecedenceMap;
static {
defaultPrecedenceMap = new HashMap<>();
defaultPrecedenceMap.put(NOT, 1);
defaultPrecedenceMap.put(AND, 2);
defaultPrecedenceMap.put(OR, 3);
}
/**
* Calls for Shunting Yard algorithm with default operator precedence.
*
* @param tokens the tokens in infix notation.
* @return the list of tokens in postfix notation, or null if
* the input token list is invalid.
*/
public static List shuntingYard(final Deque tokens) {
return shuntingYard(tokens, defaultPrecedenceMap);
}
/**
* Returns a list of tokens in postfix notation. If the input list of tokens
* is invalid (by having, say, incorrect paren
not A and (B or not C), compiles it to a circuit of logical gates \$\mathcal{C}\$, minimizes \$\mathcal{C}\$, and converts back to a (possibly shorter) boolean expression. Now, first things first: I need to be able to tokenize each input expression and change them from infix notation to postfix notation so as to be able to construct straighforwardly the actual circuit. Edsger Dijkstra's Shunting-yard algorithm does just that in linear time and space. That's what I have at this point:```
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Main {
/**
* The name of AND operator.
*/
public static final String AND = "and";
/**
* The name of NOT operator.
*/
public static final String NOT = "not";
/**
* The name of OR operator.
*/
public static final String OR = "or";
/**
* Exit command.
*/
public static final String QUIT = "quit";
/**
* The default operator precedence: NOT, AND, OR.
*/
private static final Map defaultPrecedenceMap;
static {
defaultPrecedenceMap = new HashMap<>();
defaultPrecedenceMap.put(NOT, 1);
defaultPrecedenceMap.put(AND, 2);
defaultPrecedenceMap.put(OR, 3);
}
/**
* Calls for Shunting Yard algorithm with default operator precedence.
*
* @param tokens the tokens in infix notation.
* @return the list of tokens in postfix notation, or null if
* the input token list is invalid.
*/
public static List shuntingYard(final Deque tokens) {
return shuntingYard(tokens, defaultPrecedenceMap);
}
/**
* Returns a list of tokens in postfix notation. If the input list of tokens
* is invalid (by having, say, incorrect paren
Solution
I think the code is very well written.
But, as you suggest, it should be more object oriented. I see two objects which are calling to be extracted: a Tokenizer and the InfixToPostfixConverter(better name required).
The Tokenizer should read its input from the scanner and have a method to get the next token as a string. The Converter could be feed with tokens and fill the outputQueue.
This way you separate the two problems. Moreover you can put the tokenization process in parallel with the shuntingYard algorithm without the need of a buffer to keep the tokens.
But, as you suggest, it should be more object oriented. I see two objects which are calling to be extracted: a Tokenizer and the InfixToPostfixConverter(better name required).
The Tokenizer should read its input from the scanner and have a method to get the next token as a string. The Converter could be feed with tokens and fill the outputQueue.
This way you separate the two problems. Moreover you can put the tokenization process in parallel with the shuntingYard algorithm without the need of a buffer to keep the tokens.
Context
StackExchange Code Review Q#89967, answer score: 2
Revisions (0)
No revisions yet.