I'm working on a java object oriented expression tree assignment where I need to be able to eval and print expression trees in prefix/infix/postfix formats. The assignment describes a class hierarchy with static type "Exp" and several unary and binary subclasses.
I've solved the eval part by having the unary and binary classes implement the eval() method (as dictated by the root type "Exp"), but need help with printing the expression. I've worked with this for days now and have gotten nowhere. All the help I've found online is about binary classes that has both operator and values fields (my assignment has these as two different classes). Please give me a kick in the right direction - I'll be most grateful :-)
Best wishes,
Rasmus
public interface Exp { double value(); }
public class Value implements Exp {
private double value;
public Value(double val) { this.value = val; }
public double value() { return this.value; }
}
public class Binary implements Exp {
private char op; private Exp right; private Exp left;
public Binary(char op, Exp left, Exp right) {
this.op = op; this.left = left; this.right = right;
}
}
public double value() { // sum up using recursion
switch(this.op) {
case '+': return this.left.value()+this.right.value();
case '-': return this.left.value()-this.right.value();
case '*': return this.left.value()*this.right.value();
case '/': return this.left.value()/this.right.value();
default: return Double.NaN;
}
}
}
public class Main { //calculating total ok - needs printing!
public static void Main(String[] args) {
Exp valLeft = new Value(10);
Exp valRight = new Value(5);
Exp bN1 = new Binary('+', valLeft, valRight);
Exp bN2 = new Binary('+', bN1, new Value(3));
System.out.println(bN2.value());
}
}
Here's how to do the infix. The prefix and postfix should be possible for you once you see how this one is done.
In the Exp interface, add:
String asInfix();
In the Binary class, add:
public final String asInfix() {
return "(" + left.asInfix() + " " + op + " " + right.asInfix() + ")";
}
In the Value class, add:
public final String asInfix() {
return "" + value;
}
Now you can do System.out.println(bN2.asInfix()); to display ((10.0 + 5.0) + 3.0).
Approach it in same manner. Override toString so that it calls it recursively for left and right in case of Binary, and returns the value for Value nodes.
Related
Your task is to create a class that will model a complex number.
A complex number is a number of the form a + bi, where a is the “real”
part and b is the “imaginary” part. It is based on the mathematical
premise that i2 = -1. So like the fraction class, you will define two
double data members for real and imaginary.
I will be pulling from a driver file that my professor has supplied to us. I am having no issues compiling, however am having issues running my program. I am getting a popup window from JGrasp that states "No Main methods, Java FX applications, applets, or midlets found in file.". I'm assuming that I need to put a main method into my created class however I am not sure where to put it or how to label/define it. Can someone guide me to solve this?
Thank you, my code is below.
class Complex {
private double real;
private double imaginary;
final double LIMIT = 10;// final means that this object stays the same for all.
Complex() {//constructors (there are 3, progressing in size)
real = 0;
imaginary = 0;
}
Complex(double actual) {// parameter calls what I'm assigning real to
this.real = actual;
imaginary = 0;
}
Complex(double actual, double fake) {
this.real = actual;
this.imaginary = fake;
}
public double getReal() {//accessors (there are 2, one for each parameter)
return real;
}
public double getImaginary() {
return imaginary;
}
public void setReal(double actual) {// sets real to actual, mutator.
this.real = actual;
}
public void setImaginary(double fake) {// sets imaginary to fake, mutator.
this.imaginary = fake;
}
public String toString() {//returns a String neatly in the form a + bi
return real + " " + imaginary + "i";
}
public boolean equals(Complex complexNumber) {
if(real == complexNumber.real && imaginary == complexNumber.imaginary) {//takes a complex number as a parameter type and
//returns a boolean of true if the calling object is equal to the parameter.
return true;
}
else {
return false;
}
}
public Complex add(Complex complexNumber) {
Complex temp = new Complex (0.0,0.0);
temp.real = real + complexNumber.real;
temp.imaginary = imaginary + complexNumber.imaginary;
return temp;
}
public Complex add (double val) {
Complex temp = new Complex(0.0, 0.0);
temp.real = real + val;
temp.imaginary = imaginary + val;
return temp;
}
// Override method to add fist parameter Complex object value with second Complex parameter object value
public static Complex add(Complex complexNumber, Complex c2) {
Complex temp = new Complex(0.0, 0.0);
temp.real = complexNumber.real + c2.real;
temp.imaginary = complexNumber.imaginary + c2.imaginary;
return temp;
}// End of method
// Method to check the size of implicit Complex object is greater than the LIMIT
// If greater than return true
// Otherwise return false
public boolean isBig() {
// Calculates size
double size = Math.sqrt((Math.pow(real, 2) + Math.pow(imaginary, 2)));
// Checks if size is greater than LIMIT return true
if(size > LIMIT)
return true;
// Otherwise not big return false
else
return false;
}// End of method
} // End of class
You should not put the main method of the application in this class, but a separate one, e.g. App, in the same package or higher in the package hierarchy, with a body like
public class App {
public static void main(String[] args){
System.out.println(new Complex(0.1, 0.2));
}
}
Let's say we have a simple grammar:
Program ::= Expression
Expression ::= Number
::= - ( Expression , Expression )
With this expression: -(-(8,3)4)
Returning 1.
My token stream(I splice parens and commas out) looks like this
(MINUS -)
(MINUS -)
(INTEGER 8)
(INTEGER 3)
(INTEGER 4)
So the AST would look like so
. . -
. - . 4
8..3
My question is, regarding the recursive nature of the grammar. How would a java example work given the difference expression has 2 evaluated expressions.
I've tried passing in expressions to a class constructor like so:
public class DiffExp implements LetLangExp {
LetLangExp left, right;
public DiffExp(LetLangExp l, LetLangExp r) {
left = l;
right = r;
eval();
}
}
This works for just a difference expression of -(number,number) but recursively it doesn't, because I can't seem to wrap head around the recursive nature of parsing it seems. I'm stuck on this example and i've looked online but i can't seem to equivocate this type of grammar to anything i've seen.
Essentially how do I implement a Difference Expression that is handled recursively that can take a difference expression as an operand and calculate that accordingly?
Edit: Per Markspace's request, i'm attempting to build a node structure for the parse tree. Here is the class I have right now.
class ExprNode{
String c;
static String operator;
static ExprNode operand1;
static ExprNode operand2;
public ExprNode(String num){
c = num;
operand1 = operand2 = null;
}
public static void Expr(String op, ExprNode e1, ExprNode e2){
operator = op;
operand1 = e1;
operand2 = e2;
}
}
Looks good but you'll want to separate tree building and evaluation:
public class DiffExp implements LetLangExp {
LetLangExp left, right;
public DiffExp(LetLangExp l, LetLangExp r) {
left = l;
right = r;
}
public double eval() {
return left.eval() - right.eval();
}
}
p.s. Parsing should be roughly as follows:
LetLangExpr parseProgram(LinkedList<String> tokens) {
return parseExpression(tokens);
}
LetLangExpr parseExpression(LinkedList<String> tokens) {
if ("-".equals(tokenStream.peekFirst())) {
return parseDiff(tokens);
} else {
return parseNumber(tokens);
}
}
LetLangExpr parseDiff(LinkedList<String> tokens) {
tokens.pollFirst(); // Consume "-"
LetLangExpr left = parseExpression(tokens);
LetLangExpr right = parseExpression(tokens);
return new DiffExpr(left, right);
}
LetLangExpr parseNumber(LinkedList<String> tokens) {
String numberStr = tokens.pollFirs();
double number = Double.parseDouble(numberStr);
return new NumberExpr(number);
}
You should create methods for each rule from the grammar, like:
parseProgram(String program) {
return parseExpression(program)
}
parseExpression(String expression) {
if ( isNumber(expression) ) {
return parseNumber(expression);
} else
if ( isSignedExpression(expression) ) {
String left = getLeftExpression(expression);
String right = getRightExpression(expression);
return parseExpression(left) - parseExpression(right);
}
}
parseNumber(String number) {
parsedNumber = ...
return parsedNumber;
}
Any help or advice would be greatly appreciated. I'm dooing a simple game which generates ten different, random questions. The questions can be composed from 2, 3 or 4 integers.Something like this: 552 − 4 − 101, 102 / 3 / 3, 589 − 281, 123 + 56 + 2.
The question will be displayed in a textview and then the user can take a guess, entering values into an edittext and then upon clicking a key on a custom keypad, it will check the answer, and then display the next question until it reaches 10 questions. I have a problem with imputing the answer from the code i have. No matter what i do here i cant input the answer to the randomly generated expression.
public enum Operator {
PLUS("+"), MINUS("-"), MULTIPLIER("*"), DIVIDER("/");
private String displayValue;
private Operator(String displayValue) {
this.displayValue = displayValue;
}
public String getDisplayValue() {
return displayValue;
}}
public class Question{
private List<QuestionElement> questionElements;
public Question(int sizeOfQuestionElemets) {
questionElements = new ArrayList<QuestionElement>(sizeOfQuestionElemets);
}
public void addElement(QuestionElement questionElement) {
questionElements.add(questionElement);
}
public List<QuestionElement> getElements() {
return questionElements;
}
public int size() {
return questionElements.size();
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (QuestionElement questionElement : questionElements) {
sb.append(questionElement);
}
return sb.toString().trim();
}
}
public class QuestionElement {
private int value;
private Operator operator;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Operator getOperator() {
return operator;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
#Override
public String toString() {
return value + (operator == null ? "" : " " + operator.getDisplayValue()) + " ";
}
}
public class RandomQuestions {
static QuestionElement q = new QuestionElement();
private static final int NUMBER_OF_QUESTIONS = 10;
private static final int MIN_QUESTION_ELEMENTS = 2;
private static final int MAX_QUESTION_ELEMENTS = 2;
private static final int MIN_QUESTION_ELEMENT_VALUE = 1;
private static final int MAX_QUESTION_ELEMENT_VALUE = 20;
private final Random randomGenerator = new Random();
public List<Question> getGeneratedRandomQuestions() {
List<Question> randomQuestions = new ArrayList<>(NUMBER_OF_QUESTIONS);
int randomQuestionElementsCapacity = getRandomQuestionElementsCapacity();
Question question = new Question(randomQuestionElementsCapacity);
for (int j = 0; j < randomQuestionElementsCapacity; j++) {
boolean isLastIteration = j + 1 == randomQuestionElementsCapacity;
QuestionElement questionElement = new QuestionElement();
questionElement.setValue(getRandomQuestionElementValue());
questionElement.setOperator(isLastIteration ? null
: Operator.values()[randomGenerator.nextInt(Operator.values().length)]);
question.addElement(questionElement);
}
randomQuestions.add(question);
return randomQuestions;
}
private int getRandomQuestionElementsCapacity() {
return getRandomIntegerFromRange(MIN_QUESTION_ELEMENTS, MAX_QUESTION_ELEMENTS);
}
private int getRandomQuestionElementValue() {
return getRandomIntegerFromRange(MIN_QUESTION_ELEMENT_VALUE, MAX_QUESTION_ELEMENT_VALUE);
}
private int getRandomIntegerFromRange(int min, int max) {
return randomGenerator.nextInt(max - min + 1) + min;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
RandomQuestions questionGenerator = new RandomQuestions();
List<Question> randomQuestions = questionGenerator.getGeneratedRandomQuestions();
for (Question question : randomQuestions) {
System.out.println(""+ question+"=?");
int answer = input.nextInt();
if (answer == q.getValue()) {
System.out.println("CORRECT");
}else{
System.err.println("STILL NOT WORKING");
}
}
}
}
In your main() you are printing question, reading an answer from the user and then comparing the answer to q.getValue(). q is a question element that is not related to question and always has value 0. So the trick is to answer 0 no matter what the question is, then the program will print CORRECT. :-)
I haven’t found anywhere in your code where you are calculating the correct value of the math expression. This would probably be a good first step towards checking whether the user has indeed entered the correct result.
Calculating the correct result is not really trivial if we insist on taking operator precedence into account. 4 + 3 * 2 should be 10 (not 14). I believe that reading about the Shunting-yard algorithm should get you some of the way. It’s an algorithm for parsing a math expression, which is only the first step towards calculating its value, but still a first step.
I suggest that the object-oriented approach will be that the Question object knows how to check an answer. Here is an implementation of the algorithm, simplified to the four operators, but extended to actually do the calculation:
public boolean checkAnswer(int answer) {
// calculate correct answer
// use shunting yard algorithm
Deque<Integer> outputQueue = new ArrayDeque<>();
Deque<Operator> operatorStack = new ArrayDeque<>();
for (QuestionElement element : questionElements) {
outputQueue.push(element.getValue());
Operator op = element.getOperator();
if (op != null) {
while (!operatorStack.isEmpty() && op.getPrecedence() <= operatorStack.peek().getPrecedence()) {
int operand2 = outputQueue.pop();
int operand1 = outputQueue.pop();
outputQueue.push(operatorStack.pop().apply(operand1, operand2));
}
operatorStack.push(op);
}
}
while (!operatorStack.isEmpty()) {
int operand2 = outputQueue.pop();
int operand1 = outputQueue.pop();
outputQueue.push(operatorStack.pop().apply(operand1, operand2));
}
int result = outputQueue.pop();
assert outputQueue.isEmpty();
return answer == result;
}
You notice that I have put some new demands on your Operator enum too. It has a precedence. And the + operator must know how to do addition (through its apply method), and similarly for the other operators:
PLUS("+", 1) {
#Override
public int apply(int operand1, int operand2) {
return operand1 + operand2;
}
},
// etc.
public abstract int apply(int operand1, int operand2);
and so on. 1 is the precedence; * and / have higher precedence, for example 2.
Now in main() you just need to write:
if (question.checkAnswer(answer)) {
If you decide to explain to the user that strict left-to-right evaluation is applied, it’s getting somewhat simpler:
public boolean checkAnswer(int answer) {
// calculate correct answer
// do left to right calculation
int result = questionElements.get(0).getValue();
for (int elementIndex = 1; elementIndex < questionElements.size(); elementIndex++) {
Operator op = questionElements.get(elementIndex - 1).getOperator();
result = op.apply(result, questionElements.get(elementIndex).getValue());
}
return answer == result;
}
The operators still need to have the apply method, but they no longer need the precedence.
I have a certain set of operations that I would like to be able to access dynamically by name.
If I were using JavaScript, I would represent them in a dictionary with the names of the operations as keys and the operation functions as values.
Then, for example, I could ask the user for the name of an operation, display the result of the operation if it exists, and display an error message if it doesn't exist, like so:
var operations = {
addition: function(a, b) { return a + b; },
subtraction: function(a, b) { return a - b; },
multiplication: function(a, b) { return a * b; }
// etc.
};
var a = 4, b = 7;
var opName = prompt("Enter operation name:");
if (opName in operations) {
alert("Result: " + operations[opName](a, b));
} else {
alert("The operation '" + opName + "' does not exist.");
}
How would I do the same thing in Java? I could have a Set<String> of operation names and a function that uses a switch with a case for each operation, but that requires me to repeat each operation name twice, which makes the code more brittle and more tedious to write and maintain.
Is there a reasonably concise DRY pattern for this sort of thing in Java?
This is a lot neater in Java 8 using lambdas:
Map<String, BinaryOperator<Integer>> operators = new TreeMap<>();
operators.put("add", (n1, n2) -> n1 + n2);
operators.put("minus", (n1, n2) -> n1 - n2);
if (operators.containsKey(opName)) {
return operators.get(opName).apply(n1, n2);
}
But I gather from your comments that that is not an option. An alternative is to use an enum to contain your operations so that you can add new operations in one place:
enum Operation {
PLUS {
public int operate(int arg1, int arg2) {
return arg1 + arg2;
}
},
MINUS {
public int operate(int arg1, int arg2) {
return arg1 - arg2;
}
},
...
abstract public int operate(int arg1, int arg2);
}
for (operation: Operations.values()) {
if (operation.name().equals(opName))
System.out.println("result = " + operation.operate(arg1, arg2));
return;
}
}
System.out.println("The Operation " + opName + " does not exist");
public interface Function {
double run(double a, double b);
}
public class addFunction implements Function {
double run(double a, double b) {
return a+b;
}
}
//...
Map<String, Function> operations = new HashMap<string, Function>();
operations.put("add", new addFunction());
//...
String op;
double a, b;
operations.get(op).run(a, b);
You can do the same thing in Java without using Java8:
public interface Operation<T,R> {
R perform(T... args);
}
public void test() {
Map<String, Operation> operations = new HashMap<String, Operation>() {
{
this.put("addition", new Operation<Integer, Integer>() {
public Integer perform(Integer... args) {
return args[0] + args[1];
}});
}
};
String operation = "";
Integer a = 1;
Integer b = 1;
if (operations.containsKey(operation)) {
System.out.println("Result: " + operations.get(operation).perform(a, b));
} else {
System.out.println("The operation '" + operation + "' does not exist.");
}
}
You can move that anonymous class into a separate file if you prefer that, too.
If you need arguments of different types you will have to either juggle with generics or change the argument type to Object and then do casts. Not pretty but that's the price of static typing.
Also the compiler will throw you a warning (using raw Operation) but not much to do here if you want to store operations of different types in the same map. A way out would be to make several maps for different types.
I am trying to write calculator for + - * / without conditions. The operator is stored as a string.
Is there anyway to achieve it?
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
////String Operator = "";
String L1="";
String L2="";
String op = "+";
double a = 3;
double b = 2;
//Operator p = p.
Operator p;
b = Operator.count(a, op, b);
System.out.println(b);
}
public enum Operator {
PLUS("+"), MINUS("-"), DIVIDE("/"), MULTIPLY("*");
private final String operator;
public static double count(double a,String op,double b) {
double RetVal =0;
switch (Operator.valueOf(op)) {
case PLUS:
RetVal= a + b;
case MINUS:
RetVal= a - b;
case DIVIDE:
RetVal= a / b;
case MULTIPLY:
RetVal= a * b;
}
return RetVal;
}
Operator(String operator) {
this.operator = operator;
}
// uniwersalna stała grawitacyjna (m3 kg-1 s-2)
}
}
Got this error:
Exception in thread "main" java.lang.IllegalArgumentException: No enum const class Main$Operator.+
Any clues?
You could use a strategy pattern and store a calculation strategy for each operator.
interface Calculation {
double calculate(double op1, double op2);
}
class AddCalculation implements Calculation {
double calculate(double op1, double op2) {
return op1 + op2;
}
}
//others as well
Map<String, Calculation> m = ...;
m.put("+", new AddCalculation());
During execution you then get the calculation objects from the map and execute calculate().
i think using an enum would be a nice option:
Enum Operation{
PLUS("+")
MINUS("-")
DIVIDE("/")
MULTIPLY("*")
}
then you could go with
switch(Operation.valueOf(userInputString)){
case PLUS: return a+b;
case MINUS: return a-b;
case DIVIDE: return a/b;
case MULTIPLY: return a*b;
}
how about hashing? Hash the operators as a key-value pair ("+": +). For the string operatory, hash it and grab the value. Experiment with that
As mentioned by Peter Lawrey, ScriptEngine/JavaScript might be a good choice for this. Visit this little JavaScript interpreter applet to explore the possibilities.