Как сгенерировать уравнение путем рекурсивного объединения строк в Java? - PullRequest
0 голосов
/ 04 июля 2019

Попытка реализовать генерацию математического уравнения с помощью рекурсивно конкатенируемой строки, возвращаемой классом, содержащим тот же класс, что и дочерние узлы. Окончательное уравнение содержит повторяющиеся переменные, и я хочу выяснить, как закончить рекурсию в этом сценарии.

У меня есть class1, который содержит набор / список тех же объектов class1. Также class1 содержит набор / список объектов class2 и class3. Теперь, пройдя через родительский класс, мне нужно сгенерировать выражение из всех дочерних и родительских объектов в иерархической форме. Например: Exp1 (class1) содержит Exp2 (class1), оператор (class3) и атрибут (class2). Теперь нужно сгенерировать длинное выражение через дерево объектов, таких как class1, class2 находятся слева и справа от уравнения, а оператор (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) / размер но Фактический результат: ((w + aw-c-c) / (размер () / (размер)) *

Я пытался три дня и не мог найти выход. Что здесь не так? Буду благодарен, если кто-нибудь сможет указать на ошибку

Обновленный пример кода:

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

1 Ответ

0 голосов
/ 04 июля 2019

Я не совсем нашел причину, по которой вы получаете поведение, которое вы получаете. Я подозреваю, что это происходит в коде, который вы не показываете. (Например, ничего в вашем коде не производит символы "(" и ")").

Хотя есть вероятная ошибка, в том, что на верхнем уровне вы устанавливаете exit = "1", а затем полностью пропускаете это.

Использование вами карты для передачи параметров делает ваш код более трудным для чтения, чем это необходимо.

Вы также должны взглянуть на полиморфизм, чтобы нести груз для вас.

Если я правильно понимаю вашу проблему, следующая реализация является простой; (Вложенность классов объясняется тем, что используемая мной онлайн-скрипка не позволяла использовать несколько файлов, поэтому для правильной реализации необходимо иметь отдельные классы в отдельных файлах.)

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, а не прямую конкатенацию строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...