How to generate an equation by concatenating string recursively in java? - java

Trying to implement mathematical equation generation through recursively concatenating string returned by class containing same class as child nodes. Final equation contains repeated variables and I want to figure out how to end the recursion in this scenario.
I have a class1 which contains a Set/List of the same class1 objects. Also class1 contains Set/list of class2 and class3 objects. Now traversing through the parent class, I need to generate an expression from all the child and parent objects in a hierarchical manner. For eg: Exp1(class1) contains Exp2(class1), an operator(class3) and an attribute (class2). Now have to generate a long expression through the tree of objects such as class1,class2 are on the left and right sides of the equation and operator(op) in the middle.
public Map<String,String> generatecode(Map<String,String> Codes) {
String code = Codes.get("code");
String exit = Codes.get("exit");
String operator = "";
String operand1 = "";
String operand2 = "";
Set<Class2> attrs = getAttributes();
Set<Class1> exps = getExpressions();
if(attrs.size()>=2)
exit="1";
Iterator<Class2> itr = attrs.iterator();
while (itr.hasNext()) {
class2 attr=itr.next();
if(attr.getProperty("operand").equals("operand1")) {
operand1= attr.getName();
}
else if(attr.getProperty("operand").equals("operand2")) {
operand2= attr.getName();
}
}
if(!exit.equals("1") & exps!=null & !exps.isEmpty()) {
Iterator<Class1> itr = exps.iterator();
while (itr.hasNext()) {
Class1 exp=itr.next();
if(exp.getProperty("operand").equals("operand1")) {
Map<String,String> result=exp.generatecode(Map.of("code",code,"exit",exit));
exit=result.get("exit");
if(!operand1.contains(result.get("code")))
operand1+= result.get("code");
}
if(exp.getProperty("operand").equals("operand2")) {
Map<String,String> result=exp.generatecode(Map.of("code",code,"exit",exit));
exit=result.get("exit");
if(!operand2.contains(result.get("code")))
operand2+= result.get("code");
}
}
}
code += operand1+operator+operand2;
if(!exit.equals("1"))
code="";
return Map.of("code",code,"exit",exit);
}
Main class contains
Class1 aw_plus_w = new Class1();
Class3 waw_plus = new Class3("+");
aw_plus_w.addClass2(aw, Map.of("operand", "operand2"));
aw_plus_w.addClass2(w, Map.of("operand", "operand1"));
aw_plus_w.addOperator(waw_plus);
Class1 c_minus_w = new Class1();
Class3 cw_minus = new Class3("-");
c_minus_w.addClass2(c, Map.of("operand", "operand2"));
c_minus_w.addClass1(aw_plus_w, Map.of("operand", "operand1"));
c_minus_w.addOperator(cw_minus);
Class1 fr_div_size = new Class1();
Class3 fr_div = new Class3("/");
fr_div_size.addClass1(c_minus_w, Map.of("operand", "operand1"));
fr_div_size.addClass2(size, Map.of("operand", "operand2"));
fr_div_size.addOperator(fr_div);
String code="";
fr_div_size.generatecode(Map.of("code",code,"exit","0");
Expected result: ((aw+w)-c)/size
but
Actual result: ((w+aw-c-c)/(size()/(size)))
I tried for three days and could not find a way out. What is going wrong here? It will be grateful if anyone could point out the mistake
The updated sample code:
import java.util.HashSet;
import java.util.Set;
public class MyClass {
abstract class Node
{
public abstract String getCode();
// public abstract boolean isAttribute();
}
public class Attribute extends Node
{
private String name;
public Attribute(String name)
{
this.name=name;
}
public String getCode()
{
return name;
}
}
public class Expression extends Node
{
private String name;
private Set<Attribute> arg1 = new HashSet<Attribute>();
private Set<Expression> arg2 = new HashSet<Expression>();
private String op;
public Expression(Set<Attribute> arg1,Set<Expression> arg2, String op)
{
this.arg1=arg1;
this.arg2=arg2;
this.op=" "+op+" ";
}
public String getCode()
{
String result="";
// The correct code need to be written here
return result;
}
public Expression(String name)
{
this.name=name;
}
}
public static void main(String args[]) {
MyClass cl=new MyClass();
cl.run();
}
public void run(){
Attribute x=new Attribute("x");
Expression xpx=new Expression(Set.of(x,x),null,"+");
Expression xpxdx=new Expression(Set.of(x),Set.of(xpx),"/");
System.out.println(xpxdx.getCode());
}
}

I have not quite found the reason that you get the behaivor you are getting. I suspect it arises in the code you are not showing. (For example nothing in your code produces the "(" and ")" characters).
There is a likely bug though, in that at the top level you set exit="1", and you then pass that all the way down.
Your use of map to pass parameters makes your code much harder to read than it needs to be.
You should also look at polymorphism to carry the load for you.
If I understand your problem correctly the following is a simple implementation;
(Nesting of classes is because the online fiddle I was using did not allow multiple files, proper implementation should have separate classes in separate files.)
public class MyClass {
abstract class Expression
{
public abstract String getCode();
public abstract boolean isLiteral();
}
public class Literal extends Expression
{
private String name;
public Literal(String name)
{
this.name=name;
}
public String getCode()
{
return name;
}
public boolean isLiteral()
{
return true;
}
}
public class Binary extends Expression
{
private Expression arg1;
private Expression arg2;
private String op;
public Binary(Expression arg1,Expression arg2, String op)
{
this.arg1=arg1;
this.arg2=arg2;
this.op=" "+op+" ";
}
public String getCode()
{
String result="";
if(!arg1.isLiteral()) result+="("+arg1.getCode()+")";
else result+=arg1.getCode();
result+=op;
if(!arg2.isLiteral()) result+="("+arg2.getCode()+")";
else result+=arg2.getCode();
return result;
}
public boolean isLiteral()
{
return false;
}
}
public static void main(String args[]) {
MyClass cl=new MyClass();
cl.run();
}
public void run(){
Literal x=new Literal("x");
Expression xpx=new Binary(x,x,"+");
Expression xpxdx=new Binary(xpx,x,"/");
System.out.println(xpxdx.getCode());
}
}
This can be further improved by having an enumeration for the allowed operators.
Also it really should use the StringBuilder class rather than direct string concatenation.

Related

How to access the value of string by the inheritance?

import java.util.*;
class Pilot
{
protected String PILOT = "BSIT-1A";
public static void Subject()
{
String[] subs = {"Comprog11","WebDev","Digilog12","ComProg12"};
}
public static void Teacher()
{
String[] teach = {"Ms.a","Ms.b","Ms.c","Ms.d"};
}
}
class Pilot1 extends Pilot
{
protected String PILOT1 = "BSIT-1B";
public static void main(String[]args)
{
Pilot1 obj = new Pilot1();
System.out.println(obj.PILOT);
System.out.println(obj.PILOT1);
obj.Subject();
obj.Teacher();
}
how to display the values of Subject() and Teacher() if I put inside it a String?It doesnt have any compiler issues but when I ran it display only the
BSIT-1A
BSIT-1B
my expected output is
BSIT-1A
BSIT-1B
Comprog11
Webdev
Digilog12
Comprog12
Ms.a
Ms.b
Ms.c
Ms.d
You can return the array
public String[] subject() {
return {"Comprog11","WebDev","Digilog12","ComProg12"};
}
Then remove the inheritance. You don't need it for the main method. Make the pilot constants public or pass those strings into a class constructor and add a private field with a getter method, for example
Pilot a = new Pilot("BSIT-1A");
Pilot b = new Pilot("BSIT-1B");
System.out.println(a.getCode());
System.out.println(b.getCode());
Arrays.stream(a.subject()).forEach(System.out::println);
You need the either print the values in Subject() and Teacher() or make them return the values. Also calling static methods via objects is not a
good practice. They should be invoked by the class, like Pilot1.Subject().
class Pilot
{
protected String PILOT = "BSIT-1A";
public static void Subject()
{
String[] subs = {"Comprog11","WebDev","Digilog12","ComProg12"};
for(String sub : subs){
System.out.println(sub);
}
}
public static void Teacher()
{
String[] teach = {"Ms.a","Ms.b","Ms.c","Ms.d"};
for(String t : teach){
System.out.println(t);
}
}
}

Java code example for read only interface pattern

Consider the following code for a read only interface pattern in Java:
package package2;
public interface AccountsReadOnly {
public String getValue();
}
package package1;
import package2.AccountsReadOnly;
class Accounts implements AccountsReadOnly {
private String name;
public Accounts() {
name = "unknown";
}
public String getValue() {
return name;
}
public void setValue(String name) {
this.name = name;
}
}
package package1;
public class Manager {
Accounts allAccess;
public Manager() {}
}
package package2;
public class Employee {
public AccountsReadOnly accountReadOnly;
public Employee() {}
}
public class Demo {
public static void main(String[] args) {
Manager m = new Manager();
Employee e = new Employee();
Accounts a = new Accounts();
m.allAccess = a;
m.allAccess.setValue("Andrew");
System.out.println(m.allAccess.getValue());
e.accountReadOnly = a;
System.out.println(e.accountReadOnly.getValue());
}
}
I can't understand this line as this is the first time for me to see this format:
m.allAccess.setValue("Andrew");
Is it possible to use instead of this line since they have the same reference?
m.setValue("Andrew");
Is m.allAccess a reference of the object?
Is it possible to use instead of this line since they have the same reference?
no, m.setValue("Andrew"); does not work, because the Manager-class has no function setValue
Is m.allAccess a reference of the object?
yes, allAccess references the Account-object which is set in this line: m.allAccess = a;
The getValue and setValue methods should really be named getNameand setName, because that what they do. setValueshould return a value, e.g. the account's balance.
Also nameis not read-only if you have a setter for it.

Java Passing variables around classes

I am new to java and am trying to pass variables like in the following example from one class to another, im wondering is this possible and how i would go about it if it is.
As this code does not work as it is not static.
Main Class
public class testAll
{
public static void main(String[] args)
{
One one = new One();
Two two = new Two();
}
}
The first class:
public class One
{
public int test = 4;
public int getTest()
{
return this.test;
}
}
The second class:
public class Two
{
public void value()
{
System.out.print("Var is: " + One.getTest());
}
}
Thanks,
Naz
Lets consider this, if you want to access a variable in Class A from Class B then Class A needs to know about Class B.
public class A {
public A(B classB){
this.classB = classB;
}
public void printValue(){
System.out.println(this.classB.getTest());
}
}
Now you will need to pass an instance of ClassB to ClassA in the constructor so that Class A has a reference to ClassB when it calls printValue();
ClassB b = new ClassB();
ClassA a = new ClassA(b);
b.getTest();
a.printValue();
You have to create an instance for class One first. Try this
public void value()
{
One one_object = new One();
System.out.print("Var is: " + one_object.getTest());
}
public class Two {
private One one;
public Two(One one) {
this.one = one;
}
public void printValue() {
System.out.print("Var is: " + one.getTest());
}
}
public class Main {
public static void main(String [] args) {
One one = new One();
Two two = new Two(one);
two.printValue();
}
}
There are two way - pass a reference or pass a value:
public class One {
private int value = 0;
public One(final int value) {
this.value = value;
}
public int getValue() { return value; }
}
public class Two {
private One one = null;
public Two(final int value) {
this.one = new One(value);
}
public Two(final One one) {
this.one = one;
}
public int getValue() { return one.getValue(); }
}
When passing a reference to a One instance, the value is read from One and will only change it the value held inside the One instance changes. When passing a primitive (int, boolean ...) the value is copied and "owned" by the Two instance. Read some more about the differences of references and values to grasp the idea. It's quite simple, once you get the idea.

Declaring a nested class in Java

I'm a bit confused with subclasses.
Here's my code:
public class MedHistory {
private String grafts;
private String allergies;
private String diseases;
private String surgeries;
private String medicalTreatment;
//Constructors (#2)
public MedHistory(String allergies, String diseases, String grafts,
String treatments, String surgeries) {
this.allergies=allergies;
this.diseases=diseases;
this.grafts=grafts;
this.medicalTreatment=treatments;
this.surgeries=surgeries;
}
public MedHistory() {
this.allergies="";
this.diseases="";
this.grafts="";
this.medicalTreatment="";
this.surgeries="";
}
//Getters
public String getGrafts() {
return grafts;
}
public String getAllergies() {
return allergies;
}
public String getDiseases() {
return diseases;
}
public String getSurgeries() {
return surgeries;
}
public String getMedicalTreatment() {
return medicalTreatment;
}
//Setters
public void setGrafts(String grafts) {
this.grafts = grafts;
}
public void setAllergies(String allergies) {
this.allergies = allergies;
}
public void setDiseases(String diseases) {
this.diseases = diseases;
}
public void setSurgeries(String surgeries) {
this.surgeries = surgeries;
}
public void setMedicalTreatment(String medicalTreatment) {
this.medicalTreatment = medicalTreatment;
}
public class FemMedHistory extends MedHistory {
private List<Birth> births = new ArrayList<Birth>();
//Constructors (#2)
public FemMedHistory(String allergies, String diseases, String grafts,String treatments, String surgeries, List<Birth> birthlist) {
super(allergies,allergies,grafts,treatments,surgeries);
this.births=birthlist;
}
public FemMedHistory() {
super();
this.births=null;
}
//Getter
public List<Birth> getBirths() {
return this.births;
}
//Setter
public void setBirths(List<Birth> list) {
this.births=list;
}
}
}
When I try to create an new FemMedHistory object like this:
List<Birth> list = new ArrayList<Birth>();
list.add(new Birth(new GregorianCalendar(2011,4,10),"kaisariki",4));
FemMedHistory female = new FemMedHistory("allergia2","astheneia2","emvolia2","farmekeutiki agwgi2", "xeirourgeia2", list);
I get the error:
No enclosing instance of type MedHistory is accessible. Must qualify
the allocation with an enclosing instance of type MedHistory (e.g.
x.new A() where x is an instance of MedHistory).
So, which is the right way to use a subclass?
When you declare a nested class it only available through the Outer class.
To access it outside, you will need to either make the FemMedHistory class static.
public static class FemMedHistory extends MedHistory {...}
access it through the MedHistory class
MedHistory.FemMedHistory myMedHistory = ...
or declare it in it's own Java file.
You have declared your subclass as an inner class, which means that you can't create an instance of it without first creating an instance of the containing class.
The most common way to solve this is to declare it as a separate class, which would get rid of your error.
Long story short: cut all the FemMedHistory code and paste it into FemMedHistory.java. The way it is now you have involved Java concepts which you have not yet mastered. Also, that class really does belong in a separate file.

Selecting correct Enum

I have a number of Enums each of which contain the names of attributes to be tested. The problem I have is how to select the relevant enum for the object. How can I define just a Enum variable which use throughout my code which can be set through an initalise method.
EDIT:
Sorry for the delayed reponse. I had to step away from the desk
It very well be bad design. I have a few enums as follows:
public enum AccountGrpEnum {
Account("Account"),
AccountType("AccountType"),
AcctIDSource("AcctIDSource");
private static Set<String> grpNames = new HashSet<String>(3) {{
for(AccountGrpEnum e : AccountGrpEnum.values()) {
add(e.toString());
}
}};
public static boolean contains(String name) {
return grpNames.contains(name);
}
private String name;
private AccountGrpEnum(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
Another Enum:
public enum BlockManValEnum {
avgPx("avgPx"),
quantity("quantity"),
securityIDSource("securityIDSource"),
securityID("securityID"),
blockStatus("blockStatus"),
side("side");
private static Set<String> names = new HashSet<String>(9) {{
for(BlockManValEnum e : BlockManValEnum.values()) {
add(e.toString());
}
}};
public static boolean contains(String name) {
return names.contains(name);
}
private String name;
private BlockManValEnum(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
Within my code I am checking the fields of an incoming object to see they are contained within the Enum. As follows:
if (BlockManValEnum.contains(fields[i].getName()))
however I would like it to be along the lines of
if (variableEnum.contains(fields[i].getName()))
Where variableEnum can be set at runtime.
Hope this is clearer guys
Building on previous answers.
enum Color {
RED(1),
GREEN(2),
BLUE(3);
int attrib;
Color(int attribValue) {
attrib = attribValue;
}
public Color getColorForAttrib(int attribValue) {
for(Color c : Color.values()) {
if(c.attrib == attribValue) {
return c;
}
}
throw new IllegalArgumentException("No color could be found for attrib of value " + attribValue);
}
}
...
class SomeClass {
Color c;
public void SomeClass(Color c) {
this.c = c;
}
}
...
class SomeClassUser {
public static void main(String[] args) {
Color c = Color.getColorForAttrib(Integer.valueOf(args[i]));
new SomeClass(c);
}
}
Remember that simplistically, enums are just a class, so you can add any methods you want to them. Whether or not it's a good idea depends on circumstance
Use Enum.valueOf:
Enum<?> variableEnum = AccountGrpEnum.class;
if(Enum.valueOf(variableEnum.getClass(), field[i].getName()) != null) {
doSomething();
}
Since enums are classes and thus can implement interfaces, you could create an interface which holds your contains() method and then implement that method on your enums, then use a generic method which takes a class token of a specific enum type implementing that interface (and which could be set at runtime) to test. Something like this:
CanBeTestedForContains:
public interface CanBeTestedForContains {
boolean contains(String name);
}
ColorEnum:
import java.util.HashSet;
import java.util.Set;
public enum ColorEnum implements CanBeTestedForContains {
R("red"),
B("blue");
private static Set<String> names = new HashSet<String>(3) {
{
for (final ColorEnum e : ColorEnum.values()) {
add(e.name);
}
}
};
private String name;
private ColorEnum(final String name) {
this.name = name;
}
#Override
public boolean contains(final String name) {
return names.contains(name);
}
}
SuitEnum:
import java.util.HashSet;
import java.util.Set;
public enum SuitEnum implements CanBeTestedForContains {
D("diamonds"),
H("hearts"),
C("clubs"),
S("spades");
private static Set<String> names = new HashSet<String>(3) {
{
for (final SuitEnum e : SuitEnum.values()) {
add(e.name);
}
}
};
private String name;
private SuitEnum(final String name) {
this.name = name;
}
#Override
public boolean contains(final String name) {
return names.contains(name);
}
}
ContainsSelectorTest:
public class ContainsSelectorTest {
private static <E extends Enum<E> & CanBeTestedForContains> boolean contains(final Class<E> enumClass, final String name) {
return enumClass.getEnumConstants()[0].contains(name);
}
public static void main(final String[] args) {
if (contains(ColorEnum.class, "red")) {
System.out.printf("%s contains %s\n", ColorEnum.class, "red");
}
if (contains(SuitEnum.class, "hearts")) {
System.out.printf("%s contains %s\n", SuitEnum.class, "hearts");
}
if (contains(SuitEnum.class, "red")) {
System.out.println("This shouldn't happen.");
} else {
System.out.printf("%s DOES NOT contain %s\n", SuitEnum.class, "red");
}
}
}
Output:
class ColorEnum contains red
class SuitEnum contains hearts class
class SuitEnum DOES NOT contain red

Categories

Resources