Jump to content

Recommended Posts

Posted

Boas, será que alguém me pode ajudar a criar um método que realiza expressões matemática de qualquer tipo, do género " * (floor (exp (log (2.356))))(-5.003) ".

As operações são só do tipo: sin, cos, log, e^,*,+,-,/ e depois arredondamentos etc.

O objetivo é criar este método utilizando apenas Strings, Whiles ou Switchs.

Agradeço a quem ajudar.

Posted
12 minutos atrás, HappyHippyHippo disse:

sim, claro. ajudar é uma das maiores componentes deste fórum.

qual é a dúvida ?

o meu problema é não saber sequer como fazer, eu tenho a ideia na minha cabeça mas nao consigo aplicar... nao sei mesmo como programar esse metodo, por isso é q precisava que alguem me ajudasse.

Posted
/**
 * 
 */

/**
 * @author Serhiy
 *
 */
public class Calculator {
		
	private double result;
	Memory memory1 = new Memory();
	Memory memory2 = new Memory();
	public static final String SUM = "+";
	public static final String DIF = "-";
	public static final String MUL = "*";
	public static final String DIV = "/";
	public static final String SIN = "sin";
	public static final String COS = "cos";
	public static final String LOG = "log";
	public static final String EXP = "exp";
	public static final String ABS = "abs";
	public static final String CEIL = "ceil";
	public static final String ROUND = "round";
	public static final String FLOOR = "floor";
	
	public Calculator() {
	result = 0;
	//private tem q tar em cada 1 dos construtores??
	}
	
	public Calculator(String name1) {
		memory1.setName(name1);
		result = 0;		
	}
	
	public Calculator(String name1, String name2) {
		if (!name1.equals(name2)) {
			memory1.setName(name1);
			memory2.setName(name2);
			result = 0;
		}
		else
			memory1.setName(name1);
		result = 0;
	}
	
	public void setResult(double result){
		this.result=result;
	}
	
	public double checkMemory(String memories) {
		if (memory1.getName().equals(memories))
			return memory1.getValue();
		else if (memory2.getName().equals(memories))
			return memory2.getValue();
		else
			return -1;   //fazer para dar erro
	}
	
	public String getMem1Name() {
		return memory1.getName();
	}
	
	public String getMem2Name() {
		return memory2.getName();
	}
	
	public double getMem1Value() {
		return memory1.getValue();
	}
	
	public double getMem2Value() {
		return memory2.getValue();
	}
	
	public boolean existsMem1() {
		return !memory1.getName().equals("");
	}
	
	public boolean existsMem2() {
		return !memory2.getName().equals("");
	}
	
	public boolean memoryResult(String memory) {
		if (existsMem1() && getMem1Name().equals(memory)) {
			memory1.setValue(result);
			return true;
		}
		else if (existsMem2() && getMem2Name().equals(memory)) {
			memory2.setValue(result);
			return true;
		}
		else 
			return false;
	}

		//falta fazer falsa caso haja espaço entre 2 numeros seguidos
	public String convertMemoryName(String expression) {
		String valueExpression=expression;
		if (existsMem1() && expression.contains(getMem1Name())){
			valueExpression = expression.replaceAll(getMem1Name(),""+getMem1Value());}
		else if (existsMem2() && expression.contains(getMem2Name())){
			valueExpression = expression.replaceAll(getMem2Name(),""+getMem2Value());}
		else if (existsMem1() && existsMem2() && expression.contains(getMem1Name()) && expression.contains(getMem2Name())) {
			valueExpression = expression.replaceAll(getMem1Name(),""+getMem1Value());
			valueExpression = valueExpression.replaceAll(getMem2Name(),""+getMem2Value());
		}
		return valueExpression;
	}
	
	/*public boolean checkExpressionSpaces(String expression) {
		int i=0;
		String numbers = "0123456789";
		boolean acceptingSpaces = true; 
		while (i<expression.length()) {
			if (numbers.contains(expression.substring(i, i+1)) && acceptingSpaces)
				acceptingSpaces = false;
			if (expression.substring(i, i+1).equals(" ") && !acceptingSpaces)
				return false;
			if (expression.substring(i,i+1).equals(")"))
				acceptingSpaces = true;
			i++;
		}
		return true;
	}
	
	public boolean checkOperator(String expression) {
		if (expression.equals(getMem1Name()) || expression.equals(getMem2Name()))
			return true;
		String operator = expression.substring(0,expression.indexOf("("));
		if (!operator.equals("+") && (!operator.equals("-") && !operator.equals("*") &&
			!operator.equals("/") && !operator.equals("log") && !operator.equals("exp") &&
			!operator.equals("sin") && !operator.equals("cos") && !operator.equals("abs") &&
			!operator.equals("ceil") && !operator.equals("round") && !operator.equals("floor")))
				return false;
		else
			return true;
	}
	
	public boolean checkValidExpression(String expression) {
		int countPar = 0;
		int i = 0;
		while (i<expression.length()) {
		if (expression.substring(i,i+1).equals("(")) {
			countPar++;
			i++;
		}
		else if (expression.substring(i,i+1).equals(")")) {
			countPar--;
			i++;
		}
		else
			i++;
		}
		if (countPar!=0)
			return false;
		else 
			return true;
		
	}*/
	
	public double processExpression(String expression, int start_index, int end_index) {
			String numbers="0123456789";
			String operator="-1";
			int start1=0;
			int j;
			boolean unary = true;
			if(expression.substring(start_index, start_index+1).equals("(")){
				return processExpression(expression,start_index+1,end_index);
			}
			if(start_index+1<=end_index)
				if (expression.substring(start_index, start_index+1).equals(DIF) && numbers.contains(expression.substring(start_index+1, start_index+2)))
				return -1 * processExpression(expression,start_index+1,end_index);
			if(expression.substring(start_index, start_index+1).equals(MUL)||
				expression.substring(start_index, start_index+1).equals(SUM)||
				expression.substring(start_index, start_index+1).equals(DIF)||
				expression.substring(start_index, start_index+1).equals(DIV))	{
				operator = expression.substring(start_index, start_index+1);
				start1=start_index+1;
				unary=false;
			}
			if (start_index+2<=end_index){
				if (expression.substring(start_index, start_index+3).equals(COS)||
					expression.substring(start_index, start_index+3).equals(SIN)||
					expression.substring(start_index, start_index+3).equals(LOG)||
					expression.substring(start_index, start_index+3).equals(EXP)||
					expression.substring(start_index, start_index+3).equals(ABS)) { 
						operator = expression.substring(start_index, start_index+3);
						start1=start_index+3;
				}
			}
			 if (start_index+3<=end_index){
				if (expression.substring(start_index, start_index+4).equals(CEIL)) { 
					operator = expression.substring(start_index, start_index+4);
					start1=start_index+4;
				}
			}
			 if (start_index+4<=end_index){
				if(expression.substring(start_index, start_index+5).equals(ROUND)||
					expression.substring(start_index, start_index+5).equals(FLOOR)){
					operator = expression.substring(start_index, start_index+5);
					start1=start_index+5;
				}
			}
			else {
				start1=start_index;
			}
			j=start1+1;
			
			int end1=0;
			int start2=0;
			int end2=end_index;
			
				int depth=0;
				boolean first_expression=true;
				while (j <= end_index){

					if(expression.substring(j , j+1).equals("("))
						depth++;
					else if(expression.substring(j , j+1).equals(")"))
						depth--;
					if (depth==-1 && first_expression && j<= end_index){
						end1=j;
						if (j<=end_index)
							start2=j+1;
						depth=0;
						first_expression = false;
						if (unary)
							break;
					}
					if (depth==-1 && j<= end_index){
						end2=j;
						break;
					}
					j++;
				}
				
				if (end1==0 && operator.equals("-1")){
					String number=expression.substring(start_index , start_index+1);
					for (j=start_index+1;j<=end_index;j++)
						number+= expression.substring(j , j+1);
					Double num = Double.parseDouble(number);
					return num;
					
					// caso terminal, encontra o numero.
				}
				if (operator.equals(SUM))
					return processExpression(expression,start1+1,end1-1) + processExpression(expression,start2+1,end2-1);	
				else if (operator.equals(DIF))
					return processExpression(expression,start1+1,end1-1) - processExpression(expression,start2+1,end2-1);
				else if (operator.equals(MUL))
					return processExpression(expression,start1+1,end1-1) * processExpression(expression,start2+1,end2-1);
				else if (operator.equals(DIV))
					return processExpression(expression,start1+1,end1-1) / processExpression(expression,start2+1,end2-1);
				else if (operator.equals(COS))
					return (double) Math.cos(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(SIN))
					return (double) Math.sin(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(LOG))
					return (double) Math.log(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(EXP))
					return (double) Math.exp(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(ABS))
					return (double) Math.abs(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(CEIL))
					return (double) Math.ceil(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(FLOOR))
					return (double) Math.floor(processExpression(expression,start1+1,end1-1));
				else if (operator.equals(ROUND))
					return (double) Math.round(processExpression(expression,start1+1,end1-1));
				else
					return 0;
				//tenho q fazer para dar erro
				}
	}

aqui está o codigo... aquilo que esta em comentario e o que nao funcionna... basicamente consigo fazer qualquer operaçao mas ainda preciso de uma expressão (booleana acho eu) para verificar se uma expressao e valida ou nao... Assim desso usa-la na main e caso introduza algo que nao e possivel resolver, ou que tenha parentises a mais, ou espaços entre numeros ou algo do genero, faço println que me deu "expressao mal definida"... Alguem me pode ajudar??

E ja agr, por exemplo, se eu criar uma memoria chamada "c" e depois tentar fazer "cos(0)" da-me erro, eu acho que sei pq e q me da erro, pq é suposto substituir a memoria pelo seu valor caso esteja escrita na expressão, mas neste caso n e suposto pq e um operador. Alguem tem alguma ideia de como fazer com que, caso seja um operador, nao o substitu-a??

Posted (edited)
public boolean checkOperator(String expression) {
		if (expression.equals(getMem1Name()) || expression.equals(getMem2Name()))
			return true;
		String operator = expression.substring(0,expression.indexOf("("));
		if (!operator.equals("+") && (!operator.equals("-") && !operator.equals("*") &&
			!operator.equals("/") && !operator.equals("log") && !operator.equals("exp") &&
			!operator.equals("sin") && !operator.equals("cos") && !operator.equals("abs") &&
			!operator.equals("ceil") && !operator.equals("round") && !operator.equals("floor")))
				return false;
		else
			return true;
	}

E se tiveres algo assim: 1+2+sin(...), o teu operator não está apto a ver isso. O teu if nunca vai encontrar uma correspondência valida e vai entrar na condição e retornar false.

 

Visto assim por alto e não correndo nem fazendo o debug, dá a entender que o é esse o erro.

 

P.S

 

public boolean checkValidExpression(String expression) {
		int countPar = 0;
		int i = 0;
		while (i<expression.length()) {
		if (expression.substring(i,i+1).equals("(")) {
			countPar++;
			i++;
		}
		else if (expression.substring(i,i+1).equals(")")) {
			countPar--;
			i++;
		}
		else
			i++;
		}
		if (countPar!=0)
			return false;
		else 
			return true;
		
	}

Continuando o problema de cima, aqui tens o mesmo problema. Não podes ter 1+1? Se a expressão entrar como parâmetro método retornas false porque? 

Edited by iron
Inserção de um novo ponto

Cumprimentos,
iron

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.