Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.List;
- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.regex.Pattern;
- import java.util.regex.Matcher;
- public class Calc {
- public static List<Object> tokenize(String str) {
- ArrayList<Object> list = new ArrayList<>();
- Matcher m = Pattern.compile("[.\\d]+|[A-Za-z]+|\\S+?").matcher(str);
- while(m.find()) {
- String token = m.group();
- try {
- list.add(Double.valueOf(token));
- } catch(NumberFormatException e) {
- list.add(token);
- }
- }
- for(int i = 0; i < list.size(); i++) {
- Object o = list.get(i), p = i==0?null:list.get(i-1);
- if(o.equals("+") || o.equals("-")) {
- if(p == null || !(p.equals(")") || p.equals("x") || (p instanceof Double))) {
- list.set(i, "unary" + o);
- }
- }
- }
- return list;
- }
- private static int getPriority(String operator) {
- switch(operator) {
- case "+": case "-": return 1;
- case "*": case "/": return 2;
- case "^": return 3;
- case "sin": case "cos": case "tan": case "unary-": case "unary+": return 4;
- case "(": return 0;
- }
- throw new IllegalArgumentException(operator);
- }
- public static List<Object> toRPN(List<Object> input) {
- ArrayList<Object> output = new ArrayList<>();
- LinkedList<Object> stack = new LinkedList<>();
- for(Object token: input) {
- if(token instanceof Double || token.equals("x")) output.add(token);
- else if(token.equals("(")) stack.push(token);
- else if(token.equals(")")) {
- while(!stack.peek().equals("(")) output.add(stack.pop());
- stack.pop();
- }
- else {
- while(!stack.isEmpty() && getPriority((String)stack.peek()) >= getPriority((String)token)) {
- output.add(stack.pop());
- }
- stack.push(token);
- }
- }
- while(!stack.isEmpty()) output.add(stack.pop());
- return output;
- }
- public static double eval(List<Object> rpn, double x) {
- LinkedList<Double> stack = new LinkedList<>();
- for(Object token: rpn) {
- if(token instanceof Double) stack.push((Double)token);
- else if(token.equals("x")) stack.push(x);
- else {
- switch((String)token) {
- case "+": stack.push(stack.pop() + stack.pop()); break;
- case "-": stack.push(-stack.pop() + stack.pop()); break;
- case "*": stack.push(stack.pop() * stack.pop()); break;
- case "/": stack.push(1.0/stack.pop() * stack.pop()); break;
- case "^": double exp = stack.pop(), n = stack.pop();
- stack.push(Math.pow(n, exp)); break;
- case "unary+": break;
- case "unary-": stack.push(-stack.pop()); break;
- case "sin": stack.push(Math.sin(stack.pop())); break;
- case "cos": stack.push(Math.cos(stack.pop())); break;
- case "tan": stack.push(Math.tan(stack.pop())); break;
- }
- }
- }
- if(stack.size() != 1) throw new RuntimeException();
- return stack.pop();
- }
- public static void main(String[] args) {
- String str = "-3*x^2+sin(x)";
- List<Object> tokens = tokenize(str);
- System.out.println(tokens);
- List<Object> rpn = toRPN(tokens);
- System.out.println(rpn);
- double result = eval(rpn, 2);
- System.out.println(result);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement