Java 从方程式生成图形的数据点

Java 从方程式生成图形的数据点,java,algorithm,data-structures,graph,datapoint,Java,Algorithm,Data Structures,Graph,Datapoint,我不想解方程,我的问题不是关于图形和树的数据结构。我试图从用户给出的方程中生成图形的数据点。我想要高效的算法,易于使用和维护的数据结构。我有两个解决办法 1:这很简单,我在很多应用中都看到过 String expr = "2*x+3*x"; Evaluator evaluator = new Evaluator();//I have this class for (int i = start; i < end; i += step) { evaluator.setConstant

我不想解方程,我的问题不是关于图形和树的数据结构。我试图从用户给出的方程中生成图形的数据点。我想要高效的算法,易于使用和维护的数据结构。我有两个解决办法

1:这很简单,我在很多应用中都看到过

String expr = "2*x+3*x";
Evaluator evaluator = new Evaluator();//I have this class

for (int i = start; i < end; i += step)
{
    evaluator.setConstant("x", i); 
    double ans = evaluator.evaluate(expr);
}
Equation.java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

public class Equation
{
    private final ArrayList<Boolean> operations;
    private final HashMap<String, Variable> variableHashMap;
    private int typesOfVariables;

    public Equation(Variable variable)
    {
        this.variableHashMap = new HashMap<>();
        this.operations = new ArrayList<>();
        this.typesOfVariables = 1;

        this.variableHashMap.put(variable.getSymbol(), variable);
    }

    /*Stub Method*/
    public void addVariable(Variable variable, boolean multiply)
    {
        /*
         * Currently not covering many cases
         * 1: Add two variables which have same name
         * and same pow.
         * 2: variable which are wrapped inside functions e.g sin(x)
         * and many other.*/
        if (multiply && variableHashMap.containsKey(variable.getSymbol()))
        {
            Variable var = variableHashMap.get(variable.getSymbol());
            Variable newVar = new Variable(var.getSymbol(), var.getCoefficient() * variable.getCoefficient(), var.getPow() + variable.getPow());
            /*
             * Collision chances for variables with same name but
             * with different powers*/
            this.variableHashMap.replace(var.getSymbol(), newVar);
        }
        else
        {
            ++this.typesOfVariables;
            this.variableHashMap.put(variable.getSymbol(), variable);
        }
        this.operations.add(multiply);
    }

    /*Stub Method
     *Value for every variable at any point will be different*/
    public double solveFor(double x)
    {
        if (typesOfVariables > 1)throw new IllegalArgumentException("provide values for all variables");

        Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();

        Variable var;
        double ans = 0.0;
        if (entryIterator.hasNext())
        {
            var = entryIterator.next().getValue();
            ans = var.getCoefficient() * Math.pow(x, var.getPow());
        }

        for (int i = 0; entryIterator.hasNext(); i++)
        {
            var = entryIterator.next().getValue();
            if (this.operations.get(i))ans *= var.getCoefficient() * Math.pow(x, var.getPow());
            else ans += var.getCoefficient() * Math.pow(x, var.getPow());
        }
        return ans;
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();

        if (entryIterator.hasNext())builder.append(entryIterator.next().getValue().toString());

        Variable var;
        for (int i = 0; entryIterator.hasNext(); i++)
        {
            var = entryIterator.next().getValue();
            if (this.operations.get(i))builder.append("*").append(var.toString());
            else builder.append(var.toString());
        }

        return builder.toString();
    }
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.Iterator;
公共阶级方程式
{
私有最终ArrayList操作;
私有最终HashMap变量HashMap;
私有int变量;
公共等式(变量)
{
this.variableHashMap=新HashMap();
this.operations=new ArrayList();
this.typesOfVariables=1;
this.variableHashMap.put(variable.getSymbol(),variable);
}
/*存根法*/
public void addVariable(变量、布尔乘法)
{
/*
*目前不包括很多案例
*1:添加两个具有相同名称的变量
*同样的战俘。
*2:封装在函数中的变量,例如sin(x)
*还有很多其他的*/
if(multiply&&variableHashMap.containsKey(variable.getSymbol()))
{
Variable var=variableHashMap.get(Variable.getSymbol());
变量newVar=新变量(变量getSymbol(),变量getcovercient()*变量getcovercient(),变量getPow()+变量getPow());
/*
*具有相同名称但
*不同的力量*/
这个.variableHashMap.replace(var.getSymbol(),newVar);
}
其他的
{
++这是一个变量;
this.variableHashMap.put(variable.getSymbol(),variable);
}
这个.operations.add(乘法);
}
/*存根法
*任何一点上每个变量的值都是不同的*/
公共双解算器(双x)
{
如果(typesOfVariables>1)抛出新的IllegalArgumentException(“为所有变量提供值”);
迭代器entryIterator=this.variableHashMap.entrySet().Iterator();
变量var;
双ans=0.0;
if(entryIterator.hasNext())
{
var=entryIterator.next().getValue();
ans=var.getCoefficient()*Math.pow(x,var.getPow());
}
for(int i=0;entryIterator.hasNext();i++)
{
var=entryIterator.next().getValue();
if(this.operations.get(i))ans*=var.getCoefficient()*Math.pow(x,var.getPow());
else ans+=var.getCoefficient()*Math.pow(x,var.getPow());
}
返回ans;
}
@凌驾
公共字符串toString()
{
StringBuilder=新的StringBuilder();
迭代器entryIterator=this.variableHashMap.entrySet().Iterator();
if(entryIterator.hasNext())builder.append(entryIterator.next().getValue().toString());
变量var;
for(int i=0;entryIterator.hasNext();i++)
{
var=entryIterator.next().getValue();
if(this.operations.get(i))builder.append(“*”).append(var.toString());
else builder.append(var.toString());
}
返回builder.toString();
}
}
Main.java

class Main
{
    public static void main(String[] args)
    {
        try
        {
            long t1 = System.nanoTime();

            Variable variable = new Variable("x");
            Variable variable1 = new Variable("x", -2.0, 1.0);
            Variable variable2 = new Variable("x", 3.0, 4.0);

            Equation equation = new Equation(variable);
            equation.addVariable(variable1, true);//2x+x
            equation.addVariable(variable2, true);

            for (int i = 0; i < 1000000; i++)equation.solveFor(i);//Calculate Million Data Points
            long t2 = System.nanoTime();

            System.out.println((t2-t1)/1000/1000);
            System.out.println(equation.toString());
        }
        catch (Exception e)
        {
            System.out.println("Error: " + e.getMessage());
        }
    }
}
主类
{
公共静态void main(字符串[]args)
{
尝试
{
long t1=System.nanoTime();
变量=新变量(“x”);
变量variable1=新变量(“x”、-2.0、1.0);
变量variable2=新变量(“x”,3.0,4.0);
方程=新方程(变量);
等式.addVariable(variable1,true);//2x+x
方程.addVariable(variable2,true);
对于(int i=0;i<1000000;i++)方程。solveFor(i);//计算百万个数据点
long t2=System.nanoTime();
系统输出打印项次((t2-t1)/1000/1000);
System.out.println(等式.toString());
}
捕获(例外e)
{
System.out.println(“错误:+e.getMessage());
}
}
}
我走的方向对吗? 这个问题有什么常用的算法吗

我的主要目标是效率、代码清洁度和代码可维护性

注意:我不是以英语为母语的人,所以请忽略任何语法错误


谢谢。

我认为您的第一个代码没有任何问题。是的,您的代码可能在每一步“重复标记、验证、转换为RPN、准备堆栈和队列以及最后的结果计算”,但最终所有这些都只是线性步骤数。所以我看不出它是如何让速度变慢的

我见过的最大屏幕之一是2560x1440像素,这意味着在大多数情况下,绘制图形所需的点数不到2500点

如果您的观点是代码清洁度和代码可维护性,那么很可能由5行组成的代码比由200行组成的代码要好

class Main
{
    public static void main(String[] args)
    {
        try
        {
            long t1 = System.nanoTime();

            Variable variable = new Variable("x");
            Variable variable1 = new Variable("x", -2.0, 1.0);
            Variable variable2 = new Variable("x", 3.0, 4.0);

            Equation equation = new Equation(variable);
            equation.addVariable(variable1, true);//2x+x
            equation.addVariable(variable2, true);

            for (int i = 0; i < 1000000; i++)equation.solveFor(i);//Calculate Million Data Points
            long t2 = System.nanoTime();

            System.out.println((t2-t1)/1000/1000);
            System.out.println(equation.toString());
        }
        catch (Exception e)
        {
            System.out.println("Error: " + e.getMessage());
        }
    }
}