Error catching in stacks - data-structures

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import static java.lang.Math.pow;
public class InfixExpressionEvaluator {
// Tokenizer to break up our input into tokens
StreamTokenizer tokenizer;
// Stacks for operators (for converting to postfix) and operands (for
// evaluating)
StackInterface<Character> operatorStack;
StackInterface<Double> operandStack;
//counts brackets
int Bracket1=0, Bracket2=0, count = 0;
/**
* Initializes the evaluator to read an infix expression from an input
* stream.
* #param input the input stream from which to read the expression
*/
public InfixExpressionEvaluator(InputStream input) {
// Initialize the tokenizer to read from the given InputStream
tokenizer = new StreamTokenizer(new BufferedReader(
new InputStreamReader(input)));
// StreamTokenizer likes to consider - and / to have special
meaning.
// Tell it that these are regular characters, so that they can be
parsed
// as operators
tokenizer.ordinaryChar('-');
tokenizer.ordinaryChar('/');
// Allow the tokenizer to recognize end-of-line, which marks the
end of
// the expression
tokenizer.eolIsSignificant(true);
// Initialize the stacks
operatorStack = new ArrayStack<Character>();
operandStack = new ArrayStack<Double>();
}
/**
* Parses and evaluates the expression read from the provided input
stream,
* then returns the resulting value
* #return the value of the infix expression that was parsed
*/
public Double evaluate() throws ExpressionError {
// Get the first token. If an IO exception occurs, replace it with
a
// runtime exception, causing an immediate crash.
try {
tokenizer.nextToken();
} catch (IOException e) {
throw new RuntimeException(e);
}
boolean preNum = false, preOp = false;
boolean preOpenbracket = false, preClosebracket = false;
int Bracket1 = 0, Bracket2 = 0, count = 0;
// Continue processing tokens until we find end-of-line
while (tokenizer.ttype != StreamTokenizer.TT_EOL) {
// Consider possible token type
switch (tokenizer.ttype) {
case StreamTokenizer.TT_NUMBER:
// Expression error handling
if ((preNum == true) && (count > 0)) {
throw new ExpressionError("Two operands in a row");
}
if ((preClosebracket == true) && (count > 0)) {
throw new ExpressionError("A close bracket cannot
be followed by a number");
}
// If the token is a number, process it as a double-
valued
// operand
processOperand((double) tokenizer.nval);
preOp = false;
preNum = true;
preOpenbracket = false;
preClosebracket = false;
break;
case '+':
case '-':
case '*':
case '/':
case '^':
// check for errror in input
if (count == 0) {
throw new ExpressionError("Leading off with
operator is illegal");
}
if ((preOp == true) && (count > 0)) {
throw new ExpressionError("Two operators in a
row");
}
if ((preOpenbracket == true) && (count > 0)) {
throw new ExpressionError("An open bracket cannot
be followed by an operator");
}
// If the token is any of the above characters, process
it
// is an operator
processOperator((char) tokenizer.ttype);
preOp = true;
preNum = false;
preOpenbracket = false;
preClosebracket = false;
break;
case '(':
case '[':
// Expression error handling
if ((preNum == true) && (count > 0)) {
throw new ExpressionError("An open bracket cannot
be preceded by a number");
}
// If the token is open bracket, process it as such.
Forms
// of bracket are interchangeable but must nest
properly.
processOpenBracket((char) tokenizer.ttype);
preOp = false;
preNum = false;
preOpenbracket = true;
preClosebracket = false;
Bracket1++;
break;
case ')':
case ']':
// Expression error handling
if ((preOp == true) && (count > 0)) {
throw new ExpressionError("A close bracket cannot
be preceded by a operator");
}
// If the token is close bracket, process it as such.
Forms
// of bracket are interchangeable but must nest
properly.
processCloseBracket((char) tokenizer.ttype);
preOp = false;
preNum = false;
preOpenbracket = false;
preClosebracket = true;
Bracket2++;
break;
case StreamTokenizer.TT_WORD:
// If the token is a "word", throw an expression error
throw new ExpressionError("Unrecognized token: "
+ tokenizer.sval);
default:
// If the token is any other type or value, throw an
// expression error
throw new ExpressionError("Unrecognized token: "
+ String.valueOf((char) tokenizer.ttype));
}
count++;
// Read the next token, again converting any potential IO
exception
try {
tokenizer.nextToken();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// Almost done now, but we may have to process remaining operators
in
// the operators stack
processRemainingOperators();
if (Bracket1 != Bracket2) {
throw new ExpressionError("\nNot the same number of bracket");
}
// Return the result of the evaluation -
return operandStack.pop();
}
void processOperand(double operand) {
//push operand
operandStack.push(operand);
}
void processOperator(char operator) {
// Precedence order: ^*/ level 2, +- level 1, ( and [ has lowest
level 0
while (!operatorStack.isEmpty() && hasPrecedence(operator,
operatorStack.peek())) {
// perform step 1a,1b,1c,1d
operandStack.push(applyOp(operatorStack.pop(),
operandStack.pop(), operandStack.pop()));
}
// Step 2: thisOp has more precedence than one on top of
operatorStack, push it
operatorStack.push(operator);
}
// Returns true if 'op2' has higher or same precedence as 'op1',
// otherwise returns false.
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')' || op2 == '[' || op2 == ']')
return false;
if ((op1 == '*' || op1 == '/' || op1 == '^') && (op2 == '+' || op2
== '-'))
return false;
else
return true;
}
void processOpenBracket(char openBracket) {
operatorStack.push(openBracket);
}
void processCloseBracket(char closeBracket) {
//Declare variables
char operator='0';
double a=0, b=0, c=0;
boolean correct = true;
//check for error before loop
if (operatorStack.isEmpty()) {
throw new ExpressionError("Brackets/parenthasis are uneven");
}
if (operatorStack.peek()== '(' || operatorStack.peek()=='[') {
throw new ExpressionError("There was an empty set of brackets
or unneeded use of brackets");
}
if (operandStack.isEmpty()) {
throw new ExpressionError("Too many operators");
}
//loop through stacks and pop off operators and operands
while (correct) {
operator = operatorStack.pop();
b = operandStack.pop();
a = operandStack.pop();
//check to see if next one is bracket
if (operatorStack.peek() == '(' || operatorStack.peek() == '[')
{
correct = false;
}
}
//check for errors
if (closeBracket == ')' && !operatorStack.isEmpty() &&
operatorStack.peek() != '(') {
throw new ExpressionError("Parenthesis do not match");
}
if (closeBracket == ']' && !operatorStack.isEmpty() &&
operatorStack.peek() != '[') {
throw new ExpressionError("Brackets do not match");
}
//calculate result and push it onto the stack, pop off bracket
c = applyOp(operator, b, a);
operandStack.push(c);
operatorStack.pop();
}
public static double applyOp(char op, double b, double a)
{
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '^':
return pow(a,b);
case '/':
//check for division by zero
if (b == 0)
throw new ExpressionError("No division by zero");
return a / b;
}
return 0;
}
/**
* This method is called when the evaluator encounters the end of an
* expression. It manipulates operatorStack and/or operandStack to
process
* the operators that remain on the stack, according to the Infix-to-
Postfix
* and Postfix-evaluation algorithms.
*/
void processRemainingOperators() {
//error check
double a;
if (!operatorStack.isEmpty()) {
if (operatorStack.peek()=='(' || operatorStack.peek()=='[') {
throw new ExpressionError("Uneven number of parenthesis");
}
//check for expression ending with operator
a=operandStack.pop();
if (operandStack.isEmpty()) {
throw new ExpressionError("You can not end with an
operator");
}
operandStack.push(a);
}
//process the remaining operators and answer is placed in the stack
alone
while (!operatorStack.isEmpty()) {
operandStack.push(applyOp(operatorStack.pop(),
operandStack.pop(), operandStack.pop()));
}
}
/**
* Creates an InfixExpressionEvaluator object to read from System.in,
then
* evaluates its input and prints the result.
* #param args not used
*/
public static void main(String[] args) {
System.out.println("\nInfix expression:");
InfixExpressionEvaluator evaluator =
new InfixExpressionEvaluator(System.in);
Double value = null;
try {
value = evaluator.evaluate();
} catch (ExpressionError e) {
System.out.println("ExpressionError: " + e.getMessage());
}
if (value != null) {
System.out.println(value);
} else {
System.out.println("Evaluator returned null");
}
}
}
So for this program we're supposed to use implement two stacks to do simple arithmetic. If entered correctly, the program works, but when I try to do error catching it doesn't work. I tried using counter variables for counting number of parenthesis, brackets but it didn't work. Here are some cases that didn't work:
2^(2+3*4)
2*14.5+6/5-(5*8-5/9)
10000 * [1+.20/12]^(12*4)
(4+3*2 (error catch here. program should report error because there
is no closed parenthesis)
and many more... any ideas?

Related

Check if two mathematical expressions are equivalent

I came across a question in an interview. I tried solving it but could not come up with a solution. Question is:
[Edited]
First Part: You are given two expressions with only "+" operator, check if given two expressions are mathematically equivalent.
For eg "A+B+C" is equivalent to "A+(B+C)".
Second Part : You are given two expressions with only "+" and "-" operators, check if given two expressions are mathematically equivalent.
For eg "A+B-C" is equivalent to "A-(-B+C)".
My thought process : I was thinking in terms of building an expression tree out of the given expressions and look for some kind of similarity. But I am unable to come up with a good way of checking if two expression trees are some way same or not.
Can some one help me on this :) Thanks in advance !
As long as the operations are commutative, the solution I'd propose is distribute parenthetic operations and then sort terms by 'variable', then run an aggregator across them and you should get a string of factors and symbols. Then just check the set of factors.
Aggregate variable counts until encountering an opening brace, treating subtraction as addition of the negated variable. Handle sub-expressions recursively.
The content of sub-expressions can be directly aggregated into the counts, you just need to take the sign into account properly -- there is no need to create an actual expression tree for this task. The TreeMap used in the code is just a sorted map implementation in the JDK.
The code takes advantage of the fact that the current position is part of the Reader state, so we can easily continue parsing after the closing bracket of the recursive call without needing to hand this information back to the caller explicitly somehow.
Implementation in Java (untested):
class Expression {
// Count for each variable name
Map<String, Integer> counts = new TreeMap<>();
Expression(Srring s) throws IOException {
this(new StringReader(s));
}
Expression(Reader reader) throws IOException {
int sign = 1;
while (true) {
int token = reader.read();
switch (token) {
case -1: // Eof
case ')':
return;
case '(':
add(sign, new Expression(reader));
sign = 1;
break;
case '+':
break;
case '-':
sign = -sign;
break;
default:
add(sign, String.valueOf((char) token));
sign = 1;
break;
}
}
}
void add(int factor, String variable) {
int count = counts.containsKey(variable) ? counts.get(variable) : 0;
counts.put(count + factor, variable);
}
void add(int sign, Expression expr) {
for (Map.Entry<String,Integer> entry : expr.counts.entrySet()) {
add(sign * entry.getVaue(), entry.getKey());
}
}
void equals(Object o) {
return (o instanceof Expression)
&& ((Expression) o).counts.equals(counts);
}
// Not needed for the task, just added for illustration purposes.
String toString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String,Integer> entry : expr.counts.entrySet()) {
if (sb.length() > 0) {
sb.append(" + ");
}
sb.append(entry.getValue()); // count
sb.append(entry.getKey()); // variable name
}
return sb.toString();
}
}
Compare with
new Expression("A+B-C").equals(new Expression("A-(-B+C)"))
P.S: Added a toString() method to illustrate the data structure better.
Should print 1A + 1B + -1C for the example.
P.P.P.P.S.: Fixes, simplification, better explanation.
You can parse the expressions from left to right and reduce them to a canonical form for comparison in a straightforward way; the only complication is that when you encounter a closing bracket, you need to know whether its associated opening bracket had a plus or minus in front of it; you can use a stack for that; e.g.:
function Dictionary() {
this.d = [];
}
Dictionary.prototype.add = function(key, value) {
if (!this.d.hasOwnProperty(key)) this.d[key] = value;
else this.d[key] += value;
}
Dictionary.prototype.compare = function(other) {
for (var key in this.d) {
if (!other.d.hasOwnProperty(key) || other.d[key] != this.d[key]) return false;
}
return this.d.length == other.d.length;
}
function canonize(expression) {
var tokens = expression.split('');
var variables = new Dictionary();
var sign_stack = [];
var total_sign = 1;
var current_sign = 1;
for (var i in tokens) {
switch(tokens[i]) {
case '(' : {
sign_stack.push(current_sign);
total_sign *= current_sign;
current_sign = 1;
break;
}
case ')' : {
total_sign *= sign_stack.pop();
break;
}
case '+' : {
current_sign = 1;
break;
}
case '-' : {
current_sign = -1;
break;
}
case ' ' : {
break;
}
default : {
variables.add(tokens[i], current_sign * total_sign);
}
}
}
return variables;
}
var a = canonize("A + B + (A - (A + C - B) - B) - C");
var b = canonize("-C - (-A - (B + (-C)))");
document.write(a.compare(b));

h2o DeepLearning failed: Illegal argument for field: hidden of schema: DeepLearningParametersV3: cannot convert ""200"" to type int

I wanted to execute the DeepLearning example by using H2O. But it went wrong when running "DeepLearningV3 dlBody = h2o.train_deeplearning(dlParams);"
The error message:
Illegal argument for field:
hidden of schema:
DeepLearningParametersV3:
cannot convert ""200"" to type int
This is my code, I used the default value of dlParam except "responseColumn". After it went wrong, I added one line to set value of "hidden", but the results didn't change.
private void DL() throws IOException {
//H2O start
String url = "http://localhost:54321/";
H2oApi h2o = new H2oApi(url);
//STEP 0: init a session
String sessionId = h2o.newSession().sessionKey;
//STEP 1: import raw file
String path = "hdfs://kbmst:9000/user/spark/datasets/iris.csv";
ImportFilesV3 importBody = h2o.importFiles(path, null);
System.out.println("import: " + importBody);
//STEP 2: parse setup
ParseSetupV3 parseSetupParams = new ParseSetupV3();
parseSetupParams.sourceFrames = H2oApi.stringArrayToKeyArray(importBody.destinationFrames, FrameKeyV3.class);
ParseSetupV3 parseSetupBody = h2o.guessParseSetup(parseSetupParams);
System.out.println("parseSetupBody: " + parseSetupBody);
//STEP 3: parse into columnar Frame
ParseV3 parseParams = new ParseV3();
H2oApi.copyFields(parseParams, parseSetupBody);
parseParams.destinationFrame = H2oApi.stringToFrameKey("iris.hex");
parseParams.blocking = true;
ParseV3 parseBody = h2o.parse(parseParams);
System.out.println("parseBody: " + parseBody);
//STEP 4: Split into test and train datasets
String tmpVec = "tmp_" + UUID.randomUUID().toString();
String splitExpr =
"(, " +
" (tmp= " + tmpVec + " (h2o.runif iris.hex 906317))" +
" (assign train " +
" (rows iris.hex (<= " + tmpVec + " 0.75)))" +
" (assign test " +
" (rows iris.hex (> " + tmpVec + " 0.75)))" +
" (rm " + tmpVec + "))";
RapidsSchemaV3 rapidsParams = new RapidsSchemaV3();
rapidsParams.sessionId = sessionId;
rapidsParams.ast = splitExpr;
h2o.rapidsExec(rapidsParams);
// STEP 5: Train the model
// (NOTE: step 4 is polling, which we don't require because we specified blocking for the parse above)
DeepLearningParametersV3 dlParams = new DeepLearningParametersV3();
dlParams.trainingFrame = H2oApi.stringToFrameKey("train");
dlParams.validationFrame = H2oApi.stringToFrameKey("test");
dlParams.hidden=new int[]{200,200};
ColSpecifierV3 responseColumn = new ColSpecifierV3();
responseColumn.columnName = "class";
dlParams.responseColumn = responseColumn;
System.out.println("About to train DL. . .");
DeepLearningV3 dlBody = h2o.train_deeplearning(dlParams);
System.out.println("dlBody: " + dlBody);
// STEP 6: poll for completion
JobV3 job = h2o.waitForJobCompletion(dlBody.job.key);
System.out.println("DL build done.");
// STEP 7: fetch the model
ModelKeyV3 model_key = (ModelKeyV3)job.dest;
ModelsV3 models = h2o.model(model_key);
System.out.println("models: " + models);
DeepLearningModelV3 model = (DeepLearningModelV3)models.models[0];
System.out.println("new DL model: " + model);
// STEP 8: predict!
ModelMetricsListSchemaV3 predict_params = new ModelMetricsListSchemaV3();
predict_params.model = model_key;
predict_params.frame = dlParams.trainingFrame;
predict_params.predictionsFrame = H2oApi.stringToFrameKey("predictions");
ModelMetricsListSchemaV3 predictions = h2o.predict(predict_params);
System.out.println("predictions: " + predictions);
// STEP 9: end the session
h2o.endSession();
}
I found the relative source code, but I can't understand why it goes wrong.
This is the definition of hidden.
public class DeepLearningParametersV3 extends ModelParametersSchemaV3 {{
/**
* Hidden layer sizes (e.g. [100, 100]).
*/
public int[] hidden;
//other params
}
And this is the code where the error message showed.It was the line String msg = "Illegal argument for field: " + field_name + " of schema: " + schemaClass.getSimpleName() + ": cannot convert \"" + s + "\" to type " + fclz.getSimpleName();
static <E> Object parse(String field_name, String s, Class fclz, boolean required, Class schemaClass) {
if (fclz.isPrimitive() || String.class.equals(fclz)) {
try {
return parsePrimitve(s, fclz);
} catch (NumberFormatException ne) {
String msg = "Illegal argument for field: " + field_name + " of schema: " + schemaClass.getSimpleName() + ": cannot convert \"" + s + "\" to type " + fclz.getSimpleName();
throw new H2OIllegalArgumentException(msg);
}
}
// An array?
if (fclz.isArray()) {
// Get component type
Class<E> afclz = (Class<E>) fclz.getComponentType();
// Result
E[] a = null;
// Handle simple case with null-array
if (s.equals("null") || s.length() == 0) return null;
// Handling of "auto-parseable" cases
if (AutoParseable.class.isAssignableFrom(afclz))
return gson.fromJson(s, fclz);
// Splitted values
String[] splits; // "".split(",") => {""} so handle the empty case explicitly
if (s.startsWith("[") && s.endsWith("]") ) { // It looks like an array
read(s, 0, '[', fclz);
read(s, s.length() - 1, ']', fclz);
String inside = s.substring(1, s.length() - 1).trim();
if (inside.length() == 0)
splits = new String[]{};
else
splits = splitArgs(inside);
} else { // Lets try to parse single value as an array!
// See PUBDEV-1955
splits = new String[] { s.trim() };
}
// Can't cast an int[] to an Object[]. Sigh.
if (afclz == int.class) { // TODO: other primitive types. . .
a = (E[]) Array.newInstance(Integer.class, splits.length);
} else if (afclz == double.class) {
a = (E[]) Array.newInstance(Double.class, splits.length);
} else if (afclz == float.class) {
a = (E[]) Array.newInstance(Float.class, splits.length);
} else {
// Fails with primitive classes; need the wrapper class. Thanks, Java.
a = (E[]) Array.newInstance(afclz, splits.length);
}
for (int i = 0; i < splits.length; i++) {
if (String.class == afclz || KeyV3.class.isAssignableFrom(afclz)) {
// strip quotes off string values inside array
String stripped = splits[i].trim();
if ("null".equals(stripped.toLowerCase()) || "na".equals(stripped.toLowerCase())) {
a[i] = null;
continue;
}
// Quotes are now optional because standard clients will send arrays of length one as just strings.
if (stripped.startsWith("\"") && stripped.endsWith("\"")) {
stripped = stripped.substring(1, stripped.length() - 1);
}
a[i] = (E) parse(field_name, stripped, afclz, required, schemaClass);
} else {
a[i] = (E) parse(field_name, splits[i].trim(), afclz, required, schemaClass);
}
}
return a;
}
// Are we parsing an object from a string? NOTE: we might want to make this check more restrictive.
if (! fclz.isAssignableFrom(Schema.class) && s != null && s.startsWith("{") && s.endsWith("}")) {
return gson.fromJson(s, fclz);
}
if (fclz.equals(Key.class))
if ((s == null || s.length() == 0) && required) throw new H2OKeyNotFoundArgumentException(field_name, s);
else if (!required && (s == null || s.length() == 0)) return null;
else
return Key.make(s.startsWith("\"") ? s.substring(1, s.length() - 1) : s); // If the key name is in an array we need to trim surrounding quotes.
if (KeyV3.class.isAssignableFrom(fclz)) {
if ((s == null || s.length() == 0) && required) throw new H2OKeyNotFoundArgumentException(field_name, s);
if (!required && (s == null || s.length() == 0)) return null;
return KeyV3.make(fclz, Key.make(s.startsWith("\"") ? s.substring(1, s.length() - 1) : s)); // If the key name is in an array we need to trim surrounding quotes.
}
if (Enum.class.isAssignableFrom(fclz)) {
return EnumUtils.valueOf(fclz, s);
}
// TODO: these can be refactored into a single case using the facilities in Schema:
if (FrameV3.class.isAssignableFrom(fclz)) {
if ((s == null || s.length() == 0) && required) throw new H2OKeyNotFoundArgumentException(field_name, s);
else if (!required && (s == null || s.length() == 0)) return null;
else {
Value v = DKV.get(s);
if (null == v) return null; // not required
if (!v.isFrame()) throw H2OIllegalArgumentException.wrongKeyType(field_name, s, "Frame", v.get().getClass());
return new FrameV3((Frame) v.get()); // TODO: version!
}
}
if (JobV3.class.isAssignableFrom(fclz)) {
if ((s == null || s.length() == 0) && required) throw new H2OKeyNotFoundArgumentException(s);
else if (!required && (s == null || s.length() == 0)) return null;
else {
Value v = DKV.get(s);
if (null == v) return null; // not required
if (!v.isJob()) throw H2OIllegalArgumentException.wrongKeyType(field_name, s, "Job", v.get().getClass());
return new JobV3().fillFromImpl((Job) v.get()); // TODO: version!
}
}
// TODO: for now handle the case where we're only passing the name through; later we need to handle the case
// where the frame name is also specified.
if (FrameV3.ColSpecifierV3.class.isAssignableFrom(fclz)) {
return new FrameV3.ColSpecifierV3(s);
}
if (ModelSchemaV3.class.isAssignableFrom(fclz))
throw H2O.fail("Can't yet take ModelSchemaV3 as input.");
/*
if( (s==null || s.length()==0) && required ) throw new IllegalArgumentException("Missing key");
else if (!required && (s == null || s.length() == 0)) return null;
else {
Value v = DKV.get(s);
if (null == v) return null; // not required
if (! v.isModel()) throw new IllegalArgumentException("Model argument points to a non-model object.");
return v.get();
}
*/
throw H2O.fail("Unimplemented schema fill from " + fclz.getSimpleName());
} // parse()
It looks like this could be a bug. A jira ticket has been created for this issue, you can track it here: https://0xdata.atlassian.net/browse/PUBDEV-5454?filter=-1.

Postfix Expression Calculator Validation

I need this code to be edited slightly using a loop to tell the user that their input was incorrect and then let them retry typing in a post fix expression?
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in) ;
System.out.println("Enter your two numbers and the operation with spaces between e.g 8 9 -");
String calculation=scan.nextLine();
String [] parts = calculation.split(" ");
try{
double part1 = Double.parseDouble(parts[0]);
double part2 = Double.parseDouble(parts[1]);
double answer = 0;
boolean incorrectOperation = false;
String operation = parts[2];
switch (operation) {
case "+":
answer = part1 + part2;
break;
case "-":
answer = part1 - part2;
break;
case "*":
answer = part1 * part2;
break;
case "/":
answer = part1 / part2;
break;
default:
incorrectOperation = true;
}
String ans;
if(incorrectOperation) {
ans = "Please use +, -, * or / for operation";
} else {
ans = String.valueOf(answer);
}
System.out.println(ans);
} catch (NumberFormatException e) {
System.out.println("Invalid expression " + calculation);
}
}
}
It needs to have some sort of message output using 'System.out.println' to tell the user what they have type is incorrect

Basic Recursion, Check Balanced Parenthesis

I've written software in the past that uses a stack to check for balanced equations, but now I'm asked to write a similar algorithm recursively to check for properly nested brackets and parenthesis.
Good examples: () [] ()
([]()[])
Bad examples: ( (] ([)]
Suppose my function is called: isBalanced.
Should each pass evaluate a smaller substring (until reaching a base case of 2 left)? Or, should I always evaluate the full string and move indices inward?
First, to your original question, just be aware that if you're working with very long strings, you don't want to be making exact copies minus a single letter each time you make a function call. So you should favor using indexes or verify that your language of choice isn't making copies behind the scenes.
Second, I have an issue with all the answers here that are using a stack data structure. I think the point of your assignment is for you to understand that with recursion your function calls create a stack. You don't need to use a stack data structure to hold your parentheses because each recursive call is a new entry on an implicit stack.
I'll demonstrate with a C program that matches ( and ). Adding the other types like [ and ] is an exercise for the reader. All I maintain in the function is my position in the string (passed as a pointer) because the recursion is my stack.
/* Search a string for matching parentheses. If the parentheses match, returns a
* pointer that addresses the nul terminator at the end of the string. If they
* don't match, the pointer addresses the first character that doesn't match.
*/
const char *match(const char *str)
{
if( *str == '\0' || *str == ')' ) { return str; }
if( *str == '(' )
{
const char *closer = match(++str);
if( *closer == ')' )
{
return match(++closer);
}
return str - 1;
}
return match(++str);
}
Tested with this code:
const char *test[] = {
"()", "(", ")", "", "(()))", "(((())))", "()()(()())",
"(() ( hi))) (())()(((( ))))", "abcd"
};
for( index = 0; index < sizeof(test) / sizeof(test[0]); ++index ) {
const char *result = match(test[index]);
printf("%s:\t", test[index]);
*result == '\0' ? printf("Good!\n") :
printf("Bad # char %d\n", result - test[index] + 1);
}
Output:
(): Good!
(: Bad # char 1
): Bad # char 1
: Good!
(())): Bad # char 5
(((()))): Good!
()()(()()): Good!
(() ( hi))) (())()(((( )))): Bad # char 11
abcd: Good!
There are many ways to do this, but the simplest algorithm is to simply process forward left to right, passing the stack as a parameter
FUNCTION isBalanced(String input, String stack) : boolean
IF isEmpty(input)
RETURN isEmpty(stack)
ELSE IF isOpen(firstChar(input))
RETURN isBalanced(allButFirst(input), stack + firstChar(input))
ELSE IF isClose(firstChar(input))
RETURN NOT isEmpty(stack) AND isMatching(firstChar(input), lastChar(stack))
AND isBalanced(allButFirst(input), allButLast(stack))
ELSE
ERROR "Invalid character"
Here it is implemented in Java. Note that I've switched it now so that the stack pushes in front instead of at the back of the string, for convenience. I've also modified it so that it just skips non-parenthesis symbols instead of reporting it as an error.
static String open = "([<{";
static String close = ")]>}";
static boolean isOpen(char ch) {
return open.indexOf(ch) != -1;
}
static boolean isClose(char ch) {
return close.indexOf(ch) != -1;
}
static boolean isMatching(char chOpen, char chClose) {
return open.indexOf(chOpen) == close.indexOf(chClose);
}
static boolean isBalanced(String input, String stack) {
return
input.isEmpty() ?
stack.isEmpty()
: isOpen(input.charAt(0)) ?
isBalanced(input.substring(1), input.charAt(0) + stack)
: isClose(input.charAt(0)) ?
!stack.isEmpty() && isMatching(stack.charAt(0), input.charAt(0))
&& isBalanced(input.substring(1), stack.substring(1))
: isBalanced(input.substring(1), stack);
}
Test harness:
String[] tests = {
"()[]<>{}",
"(<",
"]}",
"()<",
"(][)",
"{(X)[XY]}",
};
for (String s : tests) {
System.out.println(s + " = " + isBalanced(s, ""));
}
Output:
()[]<>{} = true
(< = false
]} = false
()< = false
(][) = false
{(X)[XY]} = true
The idea is to keep a list of the opened brackets, and if you find a closing brackt, check if it closes the last opened:
If those brackets match, then remove the last opened from the list of openedBrackets and continue to check recursively on the rest of the string
Else you have found a brackets that close a nerver opened once, so it is not balanced.
When the string is finally empty, if the list of brackes is empty too (so all the brackes has been closed) return true, else false
ALGORITHM (in Java):
public static boolean isBalanced(final String str1, final LinkedList<Character> openedBrackets, final Map<Character, Character> closeToOpen) {
if ((str1 == null) || str1.isEmpty()) {
return openedBrackets.isEmpty();
} else if (closeToOpen.containsValue(str1.charAt(0))) {
openedBrackets.add(str1.charAt(0));
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
} else if (closeToOpen.containsKey(str1.charAt(0))) {
if (openedBrackets.getLast() == closeToOpen.get(str1.charAt(0))) {
openedBrackets.removeLast();
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
} else {
return false;
}
} else {
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
}
}
TEST:
public static void main(final String[] args) {
final Map<Character, Character> closeToOpen = new HashMap<Character, Character>();
closeToOpen.put('}', '{');
closeToOpen.put(']', '[');
closeToOpen.put(')', '(');
closeToOpen.put('>', '<');
final String[] testSet = new String[] { "abcdefksdhgs", "[{aaa<bb>dd}]<232>", "[ff{<gg}]<ttt>", "{<}>" };
for (final String test : testSet) {
System.out.println(test + " -> " + isBalanced(test, new LinkedList<Character>(), closeToOpen));
}
}
OUTPUT:
abcdefksdhgs -> true
[{aaa<bb>dd}]<232> -> true
[ff{<gg}]<ttt> -> false
{<}> -> false
Note that i have imported the following classes:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public static boolean isBalanced(String str) {
if (str.length() == 0) {
return true;
}
if (str.contains("()")) {
return isBalanced(str.replaceFirst("\\(\\)", ""));
}
if (str.contains("[]")) {
return isBalanced(str.replaceFirst("\\[\\]", ""));
}
if (str.contains("{}")) {
return isBalanced(str.replaceFirst("\\{\\}", ""));
} else {
return false;
}
}
Balanced Parenthesis (JS)
The more intuitive solution is to use stack like so:
function isBalanced(str) {
const parentesis = {
'(': ')',
'[': ']',
'{': '}',
};
const closing = Object.values(parentesis);
const stack = [];
for (let char of str) {
if (parentesis[char]) {
stack.push(parentesis[char]);
} else if (closing.includes(char) && char !== stack.pop()) {
return false;
}
}
return !stack.length;
}
console.log(isBalanced('{[()]}')); // true
console.log(isBalanced('{[(]]}')); // false
console.log(isBalanced('([()]')); // false
And using recursive function (without using stack), might look something like so:
function isBalanced(str) {
const parenthesis = {
'(': ')',
'[': ']',
'{': '}',
};
if (!str.length) {
return true;
}
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (parenthesis[char]) {
for (let j = str.length - 1; j >= i; j--) {
const _char = str[j];
if (parenthesis[_char]) {
return false;
} else if (_char === parenthesis[char]) {
return isBalanced(str.substring(i + 1, j));
}
}
} else if (Object.values(parenthesis).includes(char)) {
return false;
}
}
return true;
}
console.log(isBalanced('{[()]}')); // true
console.log(isBalanced('{[(]]}')); // false
console.log(isBalanced('([()]')); // false
* As #Adrian mention, you can also use stack in the recursive function without the need of looking backwards
It doesn't really matter from a logical point of view -- if you keep a stack of all currently un-balanced parens that you pass to each step of the recursion, you'll never need to look backwards, so it doesn't matter if you cut up the string on each recursive call, or just increment an index and only look at the current first character.
In most programming languages, which have non-mutable strings, it's probably more expensive (performance-wise) to shorten the string than it is to pass a slightly larger string on the stack. On the other hand, in a language like C, you could just increment a pointer within the char array. I guess it's pretty language-dependent which of these two approaches is more 'efficient'. They're both equivalent from a conceptual point of view.
In the Scala programming language, I would do it like this:
def balance(chars: List[Char]): Boolean = {
def process(chars: List[Char], myStack: Stack[Char]): Boolean =
if (chars.isEmpty) myStack.isEmpty
else {
chars.head match {
case '(' => process(chars.tail, myStack.push(chars.head))
case ')' => if (myStack.contains('(')) process(chars.tail, myStack.pop)
else false
case '[' => process(chars.tail, myStack.push(chars.head))
case ']' => {
if (myStack.contains('[')) process(chars.tail, myStack.pop) else false
}
case _ => process(chars.tail, myStack)
}
}
val balancingAuxStack = new Stack[Char]
process(chars, balancingAuxStack)
}
Please edit to make it perfect.
I was only suggesting a conversion in Scala.
I would say this depends on your design. You could either use two counters or stack with two different symbols or you can handle it using recursion, the difference is in design approach.
func evalExpression(inStringArray:[String])-> Bool{
var status = false
var inStringArray = inStringArray
if inStringArray.count == 0 {
return true
}
// determine the complimentary bracket.
var complimentaryChar = ""
if (inStringArray.first == "(" || inStringArray.first == "[" || inStringArray.first == "{"){
switch inStringArray.first! {
case "(":
complimentaryChar = ")"
break
case "[":
complimentaryChar = "]"
break
case "{":
complimentaryChar = "}"
break
default:
break
}
}else{
return false
}
// find the complimentary character index in the input array.
var index = 0
var subArray = [String]()
for i in 0..<inStringArray.count{
if inStringArray[i] == complimentaryChar {
index = i
}
}
// if no complimetary bracket is found,so return false.
if index == 0{
return false
}
// create a new sub array for evaluating the brackets.
for i in 0...index{
subArray.append(inStringArray[i])
}
subArray.removeFirst()
subArray.removeLast()
if evalExpression(inStringArray: subArray){
// if part of the expression evaluates to true continue with the rest.
for _ in 0...index{
inStringArray.removeFirst()
}
status = evalExpression(inStringArray: inStringArray)
}
return status
}
PHP Solution to check balanced parentheses
<?php
/**
* #param string $inputString
*/
function isBalanced($inputString)
{
if (0 == strlen($inputString)) {
echo 'String length should be greater than 0';
exit;
}
$stack = array();
for ($i = 0; $i < strlen($inputString); $i++) {
$char = $inputString[$i];
if ($char === '(' || $char === '{' || $char === '[') {
array_push($stack, $char);
}
if ($char === ')' || $char === '}' || $char === ']') {
$matchablePairBraces = array_pop($stack);
$isMatchingPair = isMatchingPair($char, $matchablePairBraces);
if (!$isMatchingPair) {
echo "$inputString is NOT Balanced." . PHP_EOL;
exit;
}
}
}
echo "$inputString is Balanced." . PHP_EOL;
}
/**
* #param string $char1
* #param string $char2
* #return bool
*/
function isMatchingPair($char1, $char2)
{
if ($char1 === ')' && $char2 === '(') {
return true;
}
if ($char1 === '}' && $char2 === '{') {
return true;
}
if ($char1 === ']' && $char2 === '[') {
return true;
}
return false;
}
$inputString = '{ Swatantra (() {} ()) Kumar }';
isBalanced($inputString);
?>
It should be a simple use of stack ..
private string tokens = "{([<})]>";
Stack<char> stack = new Stack<char>();
public bool IsExpressionVaild(string exp)
{
int mid = (tokens.Length / 2) ;
for (int i = 0; i < exp.Length; i++)
{
int index = tokens.IndexOf(exp[i]);
if (-1 == index) { continue; }
if(index<mid ) stack .Push(exp[i]);
else
{
if (stack.Pop() != tokens[index - mid]) { return false; }
}
}
return true;
}
#indiv's answer is nice and enough to solve the parentheses grammar problems. If you want to use stack or do not want to use recursive method you can look at the python script on github. It is simple and fast.
BRACKET_ROUND_OPEN = '('
BRACKET_ROUND__CLOSE = ')'
BRACKET_CURLY_OPEN = '{'
BRACKET_CURLY_CLOSE = '}'
BRACKET_SQUARE_OPEN = '['
BRACKET_SQUARE_CLOSE = ']'
TUPLE_OPEN_CLOSE = [(BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE),
(BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE),
(BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE)]
BRACKET_LIST = [BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE,BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE,BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE]
def balanced_parentheses(expression):
stack = list()
left = expression[0]
for exp in expression:
if exp not in BRACKET_LIST:
continue
skip = False
for bracket_couple in TUPLE_OPEN_CLOSE:
if exp != bracket_couple[0] and exp != bracket_couple[1]:
continue
if left == bracket_couple[0] and exp == bracket_couple[1]:
if len(stack) == 0:
return False
stack.pop()
skip = True
left = ''
if len(stack) > 0:
left = stack[len(stack) - 1]
if not skip:
left = exp
stack.append(exp)
return len(stack) == 0
if __name__ == '__main__':
print(balanced_parentheses('(()())({})[]'))#True
print(balanced_parentheses('((balanced)(parentheses))({})[]'))#True
print(balanced_parentheses('(()())())'))#False

LINQ TO SQL, Dynamic query with DATE type fields

I'm building a query with the LINQ dynamic library so I don't know how many potential parameters will I have and I get an error when trying to query DATE type fields:
Operator '>=' incompatible with operand types 'DateTime' and 'String'
When I step through the debugger in the Dynamic.cs it shows that the value is of type string and the field is of type date so the problem is obvious but I have no idea how to approach it.
Any ideas?
BR
Code:
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= \"" + DateTime.Now.ToShortDateString() + "\"";
List<UserList> UserList = db.UserList.Where(SQLparam).ToList();
}
You have to use a parameterized query, e.g.
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= #1";
List<UserList> UserList = db.UserList.Where(SQLparam, new [] { DateTime.Now }).ToList();
}
I had the same problem, but with Boolean as well, so I generalised the solution
Expression ConstantParser<T>(Expression left, Token op, Expression right, Func<string, T> parser)
{
if (right is ConstantExpression)
{
try
{
var value = ((ConstantExpression)right).Value.ToString();
return Expression.Constant(parser(value));
}
catch (Exception)
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
The lines in the main function then become...
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, DateTime.Parse);
}
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, x => { DateTime? t = DateTime.Parse(x); return t; });
}
else if (left.Type == typeof(Boolean) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, Boolean.Parse);
}
Only disadvantage I can see to this approach is that if the Parse fails, we will raise and exception, but given that we throw one anyway, I don't see that it matters too much
I was in the same boat and I was able to solve this by changing one method in the Dynamic Library. It's a hack, but it allows me to use dates in expressions with equality operators (=,>,<, etc..).
I'm posting the code here in case someone still cares.
The code I added is in the if block around line 53
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression) right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
right = Expression.Constant(datevalue);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
The code basically checks if you are trying to compare a date field (left) with a string (right). And then it converts the right expression to a date constant
Here is the whole ParseComparison method:
// =, ==, !=, <>, >, >=, <, <= operators
Expression ParseComparison()
{
Expression left = ParseAdditive();
while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||
token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||
token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||
token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)
{
Token op = token;
NextToken();
Expression right = ParseAdditive();
bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||
op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;
if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
{
if (left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
right = Expression.Convert(right, left.Type);
}
else if (right.Type.IsAssignableFrom(left.Type))
{
left = Expression.Convert(left, right.Type);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (IsEnumType(left.Type) || IsEnumType(right.Type))
{
if (left.Type != right.Type)
{
Expression e;
if ((e = PromoteExpression(right, left.Type, true)) != null)
{
right = e;
}
else if ((e = PromoteExpression(left, right.Type, true)) != null)
{
left = e;
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression) right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
right = Expression.Constant(datevalue);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
op.text, ref left, ref right, op.pos);
}
switch (op.id)
{
case TokenId.Equal:
case TokenId.DoubleEqual:
left = GenerateEqual(left, right);
break;
case TokenId.ExclamationEqual:
case TokenId.LessGreater:
left = GenerateNotEqual(left, right);
break;
case TokenId.GreaterThan:
left = GenerateGreaterThan(left, right);
break;
case TokenId.GreaterThanEqual:
left = GenerateGreaterThanEqual(left, right);
break;
case TokenId.LessThan:
left = GenerateLessThan(left, right);
break;
case TokenId.LessThanEqual:
left = GenerateLessThanEqual(left, right);
break;
}
}
return left;
}
Because I had to make a comparison for a DateTime? and I had make this modification.
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression)right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
DateTime? nullableDateValue = datevalue;
right = Expression.Constant(nullableDateValue, typeof(DateTime?));
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
Thanks for the tip!

Resources