Make a Java Program to Differentiate Simple Equations

... by Bittle in Programming Help March 18, 2019

Problem

Make a java program to differentiate simple equations such as -5x^3+3x^2+5x-7.5x = -5x^3+3x^2-2.5x^1 => -15x^2+6x^12-2.5x^0

Solution

First format the string to make it workable (e.g., make -x into -1x and +x into +1x). Then split the input into tokens such as -5x^3, -3x^2, etc. After you split the string, sort by power, so all the same powers are together. After doing this, print out the differentiated equation (nx^(n-1)). There is room for improvement. I haven't caught many cases, or stress tested it with different inputs. This program is meant as a stepping stone to differentiate equations without using heavy libraries :)

MainClass.java
import java.util.ArrayList;

public class MainClass {
    public static void main(String[] args) {
        String input = "-5x^3+3x^2+5x-7.5x";

        // make workable
        input = formatInput(input);

        // first split input
        ArrayList<Token> tokens = new ArrayList<>();
        splitIntoTokens(tokens, input);

        // sort by power so it can be easier to add like terms
        tokens.sort((t1, t2) -> {
            return t1.getPower() > t2.getPower() ? -1 : 0; // Descending
        });

        printDiff(tokens);
    }

    private static String formatInput(String input) {

        input = input.trim();
        if (!(input.startsWith("-") || input.startsWith("+"))) {
            input = '+' + input;
        }

        input = input.replaceAll("\\s+", "").replaceAll("(-x)", "-1x")
                .replaceAll("(\\+x)", "+1x");
        return input;
    }

    private static void splitIntoTokens(ArrayList<Token> tokens, String input) {

        char var = 'x';
        if (input.isEmpty()) {
            return;
        }

        int varIndex = input.indexOf(var);

        System.out.println(input);
        // System.out.println(varIndex);
        if (varIndex != -1) {
            int plusIndex = input.substring(varIndex).indexOf("+");
            int minusIndex = input.substring(varIndex).indexOf("-");

            if (plusIndex == -1 && minusIndex == -1) {
                // no operator
                Token t = Token.build(input, varIndex);
                tokens.add(t);
            } else if (minusIndex != -1 && minusIndex < plusIndex || plusIndex == -1) {
                // minus found
                Token t = Token.build(input.substring(0, minusIndex + varIndex), varIndex);
                tokens.add(t);

                splitIntoTokens(tokens, input.substring(minusIndex + varIndex));
            } else {
                // plus found
                Token t = Token.build(input.substring(0, plusIndex + varIndex), varIndex);
                tokens.add(t);

                splitIntoTokens(tokens, input.substring(plusIndex + varIndex));
            }
        }
    }

    // small method to show + with positive numbers
    private static String withSign(double in) {
        return in >= 0 ? "+" + in : "" + in;
    }

    private static void printDiff(ArrayList<Token> tokens) {
        double total = tokens.get(0).getNumber();
        int p = tokens.get(0).getPower();
        for (int x = 1; x < tokens.size(); x++) {
            Token t = tokens.get(x);

            if (t.getPower() == p) {
                total += t.getNumber();
            } else {
                // power changed
                System.out.print(withSign(total * p) + "x^" + (p - 1));
                p = t.getPower();
                total = t.getNumber();
            }

        }
        System.out.print(withSign(total * p) + "x^" + (p - 1));
    }
}


Token.java
public class Token {
    private double number;
    private int power;

    public Token(double number, int power) {
        this.number = number;
        this.power = power;
    }

    public static Token build(String input, int respectIndex) {
        if (respectIndex != -1) {
            String number = input.substring(0, respectIndex);
            int pow = input.substring(respectIndex).indexOf("^");
            if (pow != -1) {
                // has a power
                return new Token(Double.parseDouble(number), Integer.parseInt(input.substring(pow + respectIndex + 1)));
            }
            return new Token(Double.parseDouble(number), 1);

        } else {
            return new Token(Double.parseDouble(input), 1);
        }
    }

    public double getNumber() {
        return number;
    }


    public int getPower() {
        return power;
    }

    @Override
    public String toString() {
        return "number = " + number + ", power = " + power;
    }
}

Comments (0)

Search Here