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