I need help in my JAVA assignment plz. kindly guide me any technique/idea to do the following. m not at advance level of programming. i already have the initial part of my assignment completed which is to make a simple command line calculator. this is the next part and i need help in only this part.
The program should take function definitions and those definitions can be used in future expressions
for eg:
def add(x,y)=(x+y)
>>> ok
def inv(x)=1/x
>>> ok
inv(add(2,2))
>>> ans : 0.25
Also four additional commands:
show; to prints all de?nitions on screen
save flename; to save all defnitions in a fle
load flename; to load all definitions from a fle
delete funname; to delete the definition corresponding to the function named funname
help in assignment of JAVA - simple command line calculator
Started by aesthete, Jan 06 2011 03:31 PM
5 replies to this topic
#1
Posted 06 January 2011 - 03:31 PM
|
|
|
#2
Posted 06 January 2011 - 11:56 PM
I assume you allready have a method that can parse the lines you give in now. It'll be needed in the invoke statement. i call it "parse" here.
I'm not sure if everything works correctly with all the substring, i 've put the expected result in comments everywhere.
This code may not be 100% errorproof. for example inv(add(2,3,5)) will eventually result in 2+3, and the 5 will be ignored.
Maybe you want to make a Functin class that contains this "0+1" line and also extra information like the number of parameters required etc etc.
Map<String, String> definitions = new HashMap<String, String>();
//def add(x,y)=(x+y)
if(line.beginsWith("def")){
String name = line.subString( 4, line.indexOf( "(" ); //name = add
String[] parameters = line.subString( line.indexOf( "(" )+1, line.indexOf( ")" ) ).split(","); //parameters = {"x","y"}
String function = line.subString("="); //function="(x+y)"
for(int i=0 ; i<parameters.length ; i++){
function.replace(parameters[i], i+"");
}
//function = "0+1"
definitions.put(name, function);
}
//inv(add(2,2))
if(line.beginsWith("inv")){
line = line.subString(4); //line = "add(2,2))
String name= line.subString(0, line.indexOf( "(" ); //name="add"
String[] parameters = line.subString( line.indexOf( "(" )+1, line.indexOf( ")" ) ).split(","); //parameters = {"2","2"}
String command = definitions.get(name); //command = "0+1"
for(int i=0 ; i<parameters.length ; i++){
command.replace(i+"", parameters[i]);
}
//command = "2+2";
parse("2+2";
}
I'm not sure if everything works correctly with all the substring, i 've put the expected result in comments everywhere.
This code may not be 100% errorproof. for example inv(add(2,3,5)) will eventually result in 2+3, and the 5 will be ignored.
Maybe you want to make a Functin class that contains this "0+1" line and also extra information like the number of parameters required etc etc.
#3
Posted 08 January 2011 - 07:46 AM
wim DC said:
I assume you allready have a method that can parse the lines you give in now. It'll be needed in the invoke statement. i call it "parse" here.
I'm not sure if everything works correctly with all the substring, i 've put the expected result in comments everywhere.
This code may not be 100% errorproof. for example inv(add(2,3,5)) will eventually result in 2+3, and the 5 will be ignored.
Maybe you want to make a Functin class that contains this "0+1" line and also extra information like the number of parameters required etc etc.
Map<String, String> definitions = new HashMap<String, String>();
//def add(x,y)=(x+y)
if(line.beginsWith("def")){
String name = line.subString( 4, line.indexOf( "(" ); //name = add
String[] parameters = line.subString( line.indexOf( "(" )+1, line.indexOf( ")" ) ).split(","); //parameters = {"x","y"}
String function = line.subString("="); //function="(x+y)"
for(int i=0 ; i<parameters.length ; i++){
function.replace(parameters[i], i+"");
}
//function = "0+1"
definitions.put(name, function);
}
//inv(add(2,2))
if(line.beginsWith("inv")){
line = line.subString(4); //line = "add(2,2))
String name= line.subString(0, line.indexOf( "(" ); //name="add"
String[] parameters = line.subString( line.indexOf( "(" )+1, line.indexOf( ")" ) ).split(","); //parameters = {"2","2"}
String command = definitions.get(name); //command = "0+1"
for(int i=0 ; i<parameters.length ; i++){
command.replace(i+"", parameters[i]);
}
//command = "2+2";
parse("2+2";
}
I'm not sure if everything works correctly with all the substring, i 've put the expected result in comments everywhere.
This code may not be 100% errorproof. for example inv(add(2,3,5)) will eventually result in 2+3, and the 5 will be ignored.
Maybe you want to make a Functin class that contains this "0+1" line and also extra information like the number of parameters required etc etc.
Thanx alot bro. this is soo helpful but there is a problem. in the descripton of my assign, we are asked to make it through a tree like mentioned below. plz guide me anything which can help me out in this specific way also.
"A function is a labelled tree
It is a tree with a name
It also contains unbound variables, i.e. the variables listed in the
parameter list (and only those ones)
When a function is used, it is necessary to bound the variables to
actual values, and then evaluate the tree as any other numerical
expression"
also, help me out in doing the following also plz.
"show prints all definitions on screen
save filename saves all definitions in a file
load filename loads all definitions from a file
delete funname deletes the definition corresponding to the function
named funname"
#4
Posted 08 January 2011 - 08:53 AM
Quote
and then evaluate the tree as any other numerical
expression"
expression"
Is it like such (A=B+C*D)?
= / \ A + / \ B * / \ C D
#5
Posted 09 January 2011 - 02:23 AM
wim DC said:
So have you allready made some trees for the previous exercise? If so could you make a sample tree?
Is it like such (A=B+C*D)?
Is it like such (A=B+C*D)?
= / \ A + / \ B * / \ C D
Yes, u r absolutely correct. it is exactly like this. but everything which i know abt these trees is the following code and nothing more. also i didnt use this tree in my previous section but it is needed in this one. i tried to understand this "tree" technique but it is very difficult for me to to get.
public class BinaryTree<E> {
private class Node {
E element;
Node left;
Node right;
void addLeft(Node n) {
left = n;
}
void addRight(Node n) {
right = n;
}
Node(E elem) { this.element = element; }
}
private Node rootnode = null;
private BinaryTree(Node n) {
rootnode = n;
}
#6
Posted 09 January 2011 - 03:28 AM
I made this BinaryTree class (+main):
I made the Node class like such:
Used an enum, because if i would've used Strings i wouldn't be able to use a switch(..) case: case:,
And an incredibly simple (static ) calculator class
--------------------------------------------------------------------------------------------------------------------
Now, if it's required for you to use generics (with the <E>) You'll have to use an interface. Basicly I replaced the generics you had by doubles.
By accepting generics, - any class will do - the calculator class won't work anymore, because +,/,*,- doesn't work with any class, it only works on int, double, float, ....
If you want to accept any class you will have to change the calculator class as followed:
This still won't work, as the problem persists, not every class has an add, minus, multiply and divide method. Thus the only option left is to create an interface which has those methods AND make sure the generics have those interfaces too.
2nd change:
The Solveable interface looks like:
And the node class looks like (more like the one you provided, with E element)
That's it :)
As test i made an extra class named "AnyClass", it obviously implements the solveable interface:
And finally, the main method to test 2 + 3*4
package calculator;
public class BinaryTree {
private Node rootnode;
public BinaryTree(Node n) {
rootnode = n;
}
public double getResult(){
return rootnode.getValue();
}
public static void main(String[] args) {
Node root = new Node(Operation.sum);
root.addLeft(new Node(2.0));
Node multiply = new Node(Operation.multiply);
root.addRight(multiply);
multiply.addLeft(new Node(3.0));
multiply.addRight(new Node(4.0));
BinaryTree tree = new BinaryTree(root);
System.out.println("result: " + tree.getResult());
}
}
The main creates a tree that does 2+3*4 and prints the result.I made the Node class like such:
package calculator;
public class Node {
Operation operation;
Double value;
Node left;
Node right;
Node(Operation operation) {
this.operation = operation;
}
Node(double value) {
this.value = value;
}
void addLeft(Node n) {
left = n;
}
void addRight(Node n) {
right = n;
}
double getValue() {
if (value == null) {
switch (operation) {
case sum:
value = Calculate.add(left.getValue(), right.getValue());
break;
case minus:
value = Calculate.minus(left.getValue(), right.getValue());
break;
case multiply:
value = Calculate.multiply(left.getValue(), right.getValue());
break;
case divide:
value = Calculate.divide(left.getValue(), right.getValue());
break;
}
}
return value;
}
}
The strength of the tree lies in the getvalue, in which i can recursively (by calling getValue again on a child element) run trough the whole tree.Used an enum, because if i would've used Strings i wouldn't be able to use a switch(..) case: case:,
package calculator;
public enum Operation {
sum, minus, multiply, divide
}
And an incredibly simple (static ) calculator class
package calculator;
public class Calculate {
public static double add(double a, double b){
return a + b;
}
public static double minus(double a, double b){
return a - b;
}
public static double multiply(double a, double b){
return a * b;
}
public static double divide(double divident, double divisor){
return divident / divisor;
}
}
And this works--------------------------------------------------------------------------------------------------------------------
Now, if it's required for you to use generics (with the <E>) You'll have to use an interface. Basicly I replaced the generics you had by doubles.
By accepting generics, - any class will do - the calculator class won't work anymore, because +,/,*,- doesn't work with any class, it only works on int, double, float, ....
If you want to accept any class you will have to change the calculator class as followed:
package calculator;
public class Calculate {
public static <E> E add(E a, E b){
return a.add(b);
}
public static <E> E minus(E a, E b){
return a.minus(b);
}
public static <E> E multiply(E a, E b){
return a.multiply(b);
}
public static <E> E divide(E divident, E divisor){
return divident.divide(divisor);
}
}
And also change the value attribute in the Node class to E.This still won't work, as the problem persists, not every class has an add, minus, multiply and divide method. Thus the only option left is to create an interface which has those methods AND make sure the generics have those interfaces too.
2nd change:
package calculator;
public class Calculate {
public static <E extends Solveable<E>> E add(E a, E b){
return a.add(b);
}
public static <E extends Solveable<E>> E minus(E a, E b){
return a.minus(b);
}
public static <E extends Solveable<E>> E multiply(E a, E b){
return a.multiply(b);
}
public static <E extends Solveable<E>> E divide(E divident, E divisor){
return divident.divide(divisor);
}
}
I also included the "operation" attribute in the generic class so the operation attribute will be moved from Node to whatever class implements solveable.The Solveable interface looks like:
package calculator;
public interface Solveable <T>{
public T add(T object);
public T minus(T object);
public T multiply(T object);
public T divide(T object);
public Operation getOperation();
}
And the node class looks like (more like the one you provided, with E element)
package calculator;
public class Node<E extends Solveable<E>> {
E element;
Node left;
Node right;
Node(E element) {
this.element = element;
}
void addLeft(Node<E> n) {
left = n;
}
void addRight(Node<E> n) {
right = n;
}
E getValue() {
if (element.getOperation() != null) {
switch (element.getOperation()) {
case sum:
element = (E) Calculate.add(left.getValue(), right.getValue());
break;
case minus:
element = (E) Calculate.minus(left.getValue(), right.getValue());
break;
case multiply:
element = (E) Calculate.multiply(left.getValue(), right.getValue());
break;
case divide:
element = (E) Calculate.divide(left.getValue(), right.getValue());
break;
}
}
return element;
}
}
That's it :)
As test i made an extra class named "AnyClass", it obviously implements the solveable interface:
package calculator;
public class AnyClass implements Solveable<AnyClass> {
private Double value;
private Operation operation = null;
public AnyClass(double value) {
this.value = value;
}
public AnyClass(Operation operation) {
this.operation = operation;
}
public AnyClass add(AnyClass object) {
return new AnyClass(value + object.value);
}
public AnyClass minus(AnyClass object) {
return new AnyClass(value - object.value);
}
public AnyClass multiply(AnyClass object) {
return new AnyClass(value * object.value);
}
public AnyClass divide(AnyClass object) {
return new AnyClass(value / object.value);
}
public Operation getOperation() {
return operation;
}
@Override
public String toString(){
return value+"";
}
}
And finally, the main method to test 2 + 3*4
public static void main(String[] args) {
Node<AnyClass> root = new Node<AnyClass>(new AnyClass(Operation.sum));
root.addLeft(new Node<AnyClass>(new AnyClass(2.0)));
Node<AnyClass> multiply = new Node<AnyClass>(new AnyClass(Operation.multiply));
root.addRight(multiply);
multiply.addLeft(new Node<AnyClass>(new AnyClass(3.0)));
multiply.addRight(new Node<AnyClass>(new AnyClass(4.0)));
BinaryTree tree = new BinaryTree(root);
System.out.println("result: " + tree.getResult());
}
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account

Back to top









