Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- /*
- * ф
- * Внимание: повторное применение преобразования для польской нотации испортит порядок выполнения.
- * В классе нет проверки на то, является ли функция записанной в обычной нотации.
- * */
- public class Rpn {
- static Map<String,Double> dictionary;
- static Map<String,Integer> priority;
- String notation;
- String function;
- public void putInDictonary(double t, String tname){
- dictionary.put(tname,t);
- }
- //Ініціує словник
- static void init_vars(){
- if(dictionary==null && priority==null){
- dictionary=new HashMap<>(15);
- priority=new HashMap<>(15);
- dictionary.put("E",Math.E);
- dictionary.put("Pi",Math.PI);
- for(String s:new String[]{"(",")"})
- priority.put(s,0);
- for(String s:new String[]{"+","-"})
- priority.put(s,1);
- for(String s:new String[]{":","*","/","cos","sin","tan","abs","sqrt","log"})
- priority.put(s,2);
- for(String s:new String[]{"**","^"})
- priority.put(s,3);
- }
- }
- public Rpn(){
- init_vars();
- }
- public String setNotation(String notation){
- this.notation=notation;
- return notation;
- }
- public double calculate(){
- return calculate(notation);
- }
- static public double calculate(String expr){
- return calculate(expr.split(" "));
- }
- //Рахує значеня формули
- static public double calculate(String[] stack){
- // for(String s:stack)System.out.println(s);
- double[] numbers=new double[stack.length];
- int point=0;
- for(int i=0;i<stack.length;i++){
- if(stack[i].matches("[0-9]+\\.?[0-9]*"))
- //stack[i].matches("[0-9]*")){//Double.NaN != Double.parseDouble(stack[i])){//
- numbers[point++]=Double.parseDouble(stack[i]);
- //Якщо у стеці є хоча б одна буква, перевірити чи є така константа, або оператор
- else if(stack[i].matches("[a-zA-Z]+"))
- if(dictionary.get(stack[i])!=null)
- numbers[point++]=dictionary.get(stack[i]);
- else if(stack[i].equalsIgnoreCase("cos"))
- numbers[point-1]=Math.cos(numbers[point-1]);
- else if(stack[i].equalsIgnoreCase("sin"))
- numbers[point-1]=Math.sin(numbers[point-1]);
- else if(stack[i].equalsIgnoreCase("abs"))
- numbers[point-1]=Math.abs(numbers[point-1]);
- else if(stack[i].equalsIgnoreCase("tan"))
- numbers[point-1]=Math.tan(numbers[point-1]);
- else if(stack[i].equalsIgnoreCase("sqrt"))
- numbers[point-1]=Math.sqrt(numbers[point-1]);
- else if(stack[i].equalsIgnoreCase("log"))
- numbers[point-1]=Math.log(numbers[point-1]);
- else ;
- //Звичайний оператор
- else if(priority.get(stack[i])!=null){
- if(stack[i].equals("*"))
- numbers[point-2]=numbers[point-2]*numbers[point-1];
- else if(stack[i].equals(":")||stack[i].equals("/") )
- numbers[point-2]=numbers[point-2]/numbers[point-1];
- else if(stack[i].equals("**") || stack[i].equals("^") )
- numbers[point-2]=Math.pow(numbers[point-2],numbers[point-1]);
- else if(stack[i].equals("+"))
- numbers[point-2]=numbers[point-2]+numbers[point-1];
- else if(stack[i].equals("-"))
- numbers[point-2]=numbers[point-2]-numbers[point-1];
- else continue;
- point--;
- }
- }
- return numbers[0]+0;
- }
- // Припустимо що вираз розділен пробілами
- public String buildNotation(String expr){
- String new_expr =expr.replace(",",".");
- notation = buildNotation( new_expr.split(" "));
- return notation;
- }
- //Будує з звичайної нотації польску
- public String buildNotation(String[] expr){
- // j-out[] index; k-stack[]index
- int j=0,k=0;
- String out[]=new String[expr.length],stack[]=new String[expr.length];
- for(int i=0;i<expr.length;i++)
- //Число
- if(expr[i].matches("[0-9]+\\.?[0-9]*") && !expr[i].matches("[a-zA-Z]"))
- out[j++]=expr[i];
- //Змінна чи константа
- else if(!dictionary.isEmpty()&& dictionary.get(expr[i])!=null)
- out[j++]=expr[i];
- //Функція
- else if(expr[i].matches("[a-zA-Z]*"))
- if(priority.get(expr[i])!=null) stack[k++]=expr[i];
- else out[j++]=expr[i];
- //Дужка
- else if(expr[i].contains("("))
- stack[k++]="(";
- //Друга дужка
- else if(expr[i].contains(")"))
- while(k>0)
- if(stack[k-1].contains("(")){
- stack[--k]=" ";
- break;
- }
- else out[j++] = stack[--k];
- //Звичайні оператори
- else if(expr[i].matches("[*:/^+-]")){
- while(k>0)
- if(priority.get(stack[k-1]) >= priority.get(expr[i]) )
- out[j++]=stack[--k];
- else break;
- stack[k++]=expr[i];
- }
- //Кінець циклу
- //Перевірка балансу дужок та розгруз стеку
- for(int i=k-1; i>=0;i--)
- if(stack[i].contains("(") || stack[i].contains(")"))return "3rr0r";
- else out[j++]=stack[i];
- StringJoiner result=new StringJoiner(" ");
- for(String i:out)if(i!=null)result.add(i);
- return result.toString();
- }
- //Будуе графік по заданих параметрах
- public TreeSet<Pair<Double, Double>> function(double a, double b, double h, String variable){
- if(a>b)return null;
- TreeSet<Pair<Double,Double>> f=new TreeSet<>();
- dictionary.put(variable, a);
- int n=(int)((b-a)/h)+1;
- for(double t=a;t<b;t+=h) {
- dictionary.replace(variable, t);
- f.add(new Pair(t,calculate()));
- }
- dictionary.remove(variable,a+h*n);
- return f;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement