De vez enquanto existe a necessidade de tratar expressões aritméticas básicas (adição, subtração, multiplicação e divisão) que retornem o resultado em valores reais considerando a prioridade das operações a serem efetuadas.
O código abaixo permitir passar como parâmetro uma String com a expressão aritmética a ser interpretada e retornar um valor do tipo Double.
A prioridade das operações é: parênteses "()", divisão "/", multiplicação "*", adição "+" e subtração "-".
Podem ser utilizados os símbolos {} e [] para separar as expressões.
O nome da classe é: Expressao.
O método público é: calcularExpressao.
Exemplo de uso:
Expressao expressao = new Expressao();
Double resultado = expressao.calcularExpressao("((10/5)+10*2+(20/2))");
Abaixo segue o código do interpretador. Pode ser alterado para permitir outras operações.
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
/**
*
* @author Francisco Januario
* @date 14/09/2011
* @modified 13/01/2012
* @version 1.1
*
*/
public class Expressao {
private int id;
private int nivel;
private int posicao1;
private int posicao2;
private String expressao;
private Double resultado;
// O simbolo "M" (pode ser outro) para a constante operadorMenos
// é utilizado para substituir o operador "-" durante o cálculo
// com número negativos.
private static String operadorMenos = "M";
public Expressao(){
}
private boolean isNumero(String numero){
boolean bNumero = true;
if(!numero.equals("0")&&!numero.equals("1")&&
!numero.equals("2")&&!numero.equals("3")&&
!numero.equals("4")&&!numero.equals("5")&&
!numero.equals("6")&&!numero.equals("7")&&
!numero.equals("8")&&!numero.equals("9")&&
!numero.equals(".")&&!numero.equals(",")&&
!numero.equals(operadorMenos)){
bNumero = false;
}
return bNumero;
}
private Double calcular(String expressao){
Double resultado = 0.0;
String sExpressao = expressao;
if(sExpressao.charAt(0)=='-')
sExpressao = operadorMenos + sExpressao.substring(1);
Double res = 0.0;
boolean oper;
while(sExpressao.contains("/")||
sExpressao.contains("*")||
sExpressao.contains("+")||
sExpressao.contains("-")){
oper = false;
Double vl1 = 0.0;
Double vl2 = 0.0;
String sl1 = "";
String sl2 = "";
int iPos1 = 0;
int iPos2 = 0;
try{
// DIVISÃO
if(!oper&&sExpressao.contains("/")){
int i;
// Capturando o primeiro numero antes do operador
for(i=sExpressao.indexOf("/")-1; i >= 0; i--){
if(isNumero(sExpressao.substring(i, i+1)))
sl1 = sExpressao.substring(i, i+1) + sl1;
else{
break;
}
}
iPos1 = i + 1;
if(sl1.contains(","))
sl1 = sl1.substring(0, sl1.indexOf(",")-1) + "." + sl1.substring(sl1.indexOf(",")+1);
if(sl1.contains(operadorMenos))
sl1 = sl1.replace(operadorMenos, "-");
vl1 = Double.parseDouble(sl1);
// Capturando o primeiro numero antes do operador
for(i=sExpressao.indexOf("/")+1; i<sExpressao.length(); i++){
if(isNumero(sExpressao.substring(i, i+1)))
sl2 = sl2 + sExpressao.substring(i, i+1);
else{
break;
}
}
iPos2 = i - 1;
if(sl2.contains(","))
sl2 = sl2.substring(0, sl2.indexOf(",")-1) + "." + sl2.substring(sl2.indexOf(",")+1);
vl2 = Double.parseDouble(sl2);
// Calculando o resultado
if(vl2 > 0)
res = vl1 / vl2;
else
res = 0.0;
sExpressao = sExpressao.substring(0, iPos1) + new Double(res).toString() +
sExpressao.substring(iPos2+1);
oper = true;
}
// MULTIPLICAÇÃO
if(!oper&&sExpressao.contains("*")){
// Capturando o primeiro numero antes do operador
int i;
for(i=sExpressao.indexOf("*")-1; i >= 0; i--){
if(isNumero(sExpressao.substring(i, i+1)))
sl1 = sExpressao.substring(i, i+1) + sl1;
else{
break;
}
}
iPos1 = i + 1;
if(sl1.contains(","))
sl1 = sl1.substring(0, sl1.indexOf(",")-1) + "." + sl1.substring(sl1.indexOf(",")+1);
if(sl1.contains(operadorMenos))
sl1 = sl1.replace(operadorMenos, "-");
vl1 = Double.parseDouble(sl1);
// Capturando o primeiro numero antes do operador
for(i=sExpressao.indexOf("*")+1; i<sExpressao.length(); i++){
if(isNumero(sExpressao.substring(i, i+1)))
sl2 = sl2 + sExpressao.substring(i, i+1);
else{
break;
}
}
iPos2 = i - 1;
if(sl2.contains(","))
sl2 = sl2.substring(0, sl2.indexOf(",")-1) + "." + sl2.substring(sl2.indexOf(",")+1);
vl2 = Double.parseDouble(sl2);
// Calculando o resultado
res = vl1 * vl2;
sExpressao = sExpressao.substring(0, iPos1) + new Double(res).toString() +
sExpressao.substring(iPos2+1);
oper = true;
}
// ADIÇÃO
if(!oper&&sExpressao.contains("+")){
// Capturando o primeiro numero antes do operador
int i;
for(i=sExpressao.indexOf("+")-1; i >= 0; i--){
if(isNumero(sExpressao.substring(i, i+1)))
sl1 = sExpressao.substring(i, i+1) + sl1;
else{
break;
}
}
iPos1 = i + 1;
if(sl1.contains(","))
sl1 = sl1.substring(0, sl1.indexOf(",")-1) + "." + sl1.substring(sl1.indexOf(",")+1);
if(sl1.contains(operadorMenos))
sl1 = sl1.replace(operadorMenos, "-");
vl1 = Double.parseDouble(sl1);
// Capturando o primeiro numero antes do operador
for(i=sExpressao.indexOf("+")+1; i<sExpressao.length(); i++){
if(isNumero(sExpressao.substring(i, i+1)))
sl2 = sl2 + sExpressao.substring(i, i+1);
else{
break;
}
}
iPos2 = i - 1;
if(sl2.contains(","))
sl2 = sl2.substring(0, sl2.indexOf(",")-1) + "." + sl2.substring(sl2.indexOf(",")+1);
vl2 = Double.parseDouble(sl2);
// Calculando o resultado
res = vl1 + vl2;
sExpressao = sExpressao.substring(0, iPos1) + new Double(res).toString() +
sExpressao.substring(iPos2+1);
oper = true;
}
// SUBTRAÇÃO
if(!oper&&sExpressao.contains("-")){
// Capturando o primeiro numero antes do operador
int i;
for(i=sExpressao.indexOf("-")-1; i >= 0; i--){
if(isNumero(sExpressao.substring(i, i+1)))
sl1 = sExpressao.substring(i, i+1) + sl1;
else{
break;
}
}
iPos1 = i + 1;
if(sl1.contains(","))
sl1 = sl1.substring(0, sl1.indexOf(",")-1) + "." + sl1.substring(sl1.indexOf(",")+1);
if(sl1.contains(operadorMenos))
sl1 = sl1.replace(operadorMenos, "-");
vl1 = Double.parseDouble(sl1);
// Capturando o primeiro numero antes do operador
for(i=sExpressao.indexOf("-")+1; i<sExpressao.length(); i++){
if(isNumero(sExpressao.substring(i, i+1)))
sl2 = sl2 + sExpressao.substring(i, i+1);
else{
break;
}
}
iPos2 = i - 1;
if(sl2.contains(","))
sl2 = sl2.substring(0, sl2.indexOf(",")-1) + "." + sl2.substring(sl2.indexOf(",")+1);
vl2 = Double.parseDouble(sl2);
// Calculando o resultado
res = vl1 - vl2;
sExpressao = sExpressao.substring(0, iPos1) + new Double(res).toString() +
sExpressao.substring(iPos2+1);
oper = true;
}
if(sExpressao.charAt(0)=='-')
sExpressao = operadorMenos + sExpressao.substring(1);
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Expressão Inválida...");
return 0.0;
}
}
if(sExpressao.charAt(0)==operadorMenos.charAt(0))
sExpressao = "-" + sExpressao.substring(1);
resultado = Double.parseDouble(sExpressao);
return resultado;
}
private String prepararExpressao(String expressao){
String sExpressao = "";
if(expressao != null)
sExpressao = expressao;
else
sExpressao = "";
// Tirando todo espaço em branco
sExpressao = sExpressao.replaceAll(" ", "");
// Subsituir "[" e "]"
sExpressao = sExpressao.replace("[", "(");
sExpressao = sExpressao.replace("]", ")");
// Subsituir "{" e "}"
sExpressao = sExpressao.replace("{", "(");
sExpressao = sExpressao.replace("}", ")");
return "(" + sExpressao + ")";
}
public Double calcularExpressao(String expressao){
Double resultado = 0.0;
String sExpressao = prepararExpressao(expressao);
List<Expressao> expressoes = new ArrayList<Expressao> ();
int nivel = 0;
int id = 1;
for(int i=0; i<sExpressao.length(); i++){
if(sExpressao.charAt(i)=='('){
nivel++;
Expressao exp = new Expressao();
exp.setId(id);
exp.setNivel(nivel);
exp.setPosicao1(i);
expressoes.add(exp);
id++;
}
if(sExpressao.charAt(i)==')'){
for(int j=0; j<expressoes.size(); j++){
Expressao exp = expressoes.get(j);
if((exp.getPosicao2()==0)&&exp.getNivel()==nivel){
exp.setPosicao2(i);
exp.setExpressao(sExpressao.substring(exp.getPosicao1()+1, i));
expressoes.set(j, exp);
}
}
nivel--;
}
}
nivel = 0;
for(Expressao exp : expressoes){
if(exp.getNivel() > nivel)
nivel = exp.getNivel();
}
Double res = 0.00;
int i = nivel;
while(i >= 1){
for(int j=0; j<expressoes.size(); j++){
Expressao exp = expressoes.get(j);
if(exp.getNivel() == i){
if(!exp.getExpressao().contains("(")&&(exp.getResultado()==null)){
res = calcular(exp.getExpressao());
exp.setResultado(res);
expressoes.set(j, exp);
}
}
}
i--;
}
i = expressoes.size()-1;
boolean prox;
String sExpressao2 = "";
while(i >= 0){
Expressao exp = expressoes.get(i);
prox = true;
if(exp.getResultado()==null){
for(int j=0; j<expressoes.size(); j++){
Expressao exp2 = expressoes.get(j);
if(exp.getExpressao().contains("("+exp2.getExpressao()+")")&&
(exp2.getResultado()!=null)){
sExpressao2 = exp.getExpressao().replace("("+exp2.getExpressao()+")",
new Double(exp2.getResultado()).toString());
if(!sExpressao2.contains("(")){
res = calcular(sExpressao2);
exp.setResultado(res);
prox = false;
}else{
exp.setExpressao(sExpressao2);
}
expressoes.set(i, exp);
i = expressoes.size()-1;
}
}
}
if(prox)
i--;
}
resultado = expressoes.get(0).getResultado();
return resultado;
}
private Double getResultado() {
return resultado;
}
private void setResultado(Double resultado) {
this.resultado = resultado;
}
private String getExpressao() {
return expressao;
}
private void setExpressao(String expressao) {
this.expressao = expressao;
}
private int getId() {
return id;
}
private void setId(int id) {
this.id = id;
}
private int getNivel() {
return nivel;
}
private void setNivel(int nivel) {
this.nivel = nivel;
}
private int getPosicao1() {
return posicao1;
}
private void setPosicao1(int posicao1) {
this.posicao1 = posicao1;
}
private int getPosicao2() {
return posicao2;
}
private void setPosicao2(int posicao2) {
this.posicao2 = posicao2;
}
}