首页 > 解决方案 > java - 如何通过在java中递归连接字符串来生成方程?

问题描述

尝试通过递归连接包含与子节点相同的类的类返回的字符串来实现数学方程生成。最终方程包含重复的变量,我想弄清楚如何在这种情况下结束递归。

我有一个包含相同 class1 对象的 Set/List 的 class1。class1 还包含 class2 和 class3 对象的集合/列表。现在遍历父类,我需要以分层方式从所有子对象和父对象生成表达式。例如:Exp1(class1) 包含 Exp2(class1)、一个运算符 (class3) 和一个属性 (class2)。现在必须通过对象树生成一个长表达式,例如 class1,class2 在等式的左右两侧,operator(op) 在中间。

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);
}

主类包含

    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");

预期结果:((aw+w)-c)/size 但实际结果:((w+aw-cc)/(size()/(size)))

我试了三天,找不到出路。这里出了什么问题?如果有人能指出错误,将不胜感激

更新后的示例代码:

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());
    }
}

标签: javaoop

解决方案


我还没有完全找到你得到你得到的行为的原因。我怀疑它出现在您未显示的代码中。(例如,您的代码中没有任何内容产生“(”和“)”字符)。

但是可能存在一个错误,在顶层您设置了 exit="1",然后您将其一直向下传递。

您使用 map 传递参数使您的代码比它需要的更难阅读。

您还应该查看多态性来为您承担负载。

如果我正确理解您的问题,以下是一个简单的实现;(类的嵌套是因为我使用的在线小提琴不允许多个文件,正确的实现应该在单独的文件中有单独的类。)

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());
    }
}

这可以通过对允许的运算符进行枚举来进一步改进。

此外,它确实应该使用 StringBuilder 类而不是直接字符串连接。


推荐阅读