• programación en java ayúdenme con esto

 #458987  por fjerez186
 02 Nov 2014, 00:13
package cal;

import java.util.Scanner;

public class Cal {

public static void main(String[] args ) {
// TODO Auto-generated method stub
Scanner teclado = new Scanner(System.in);
String op;
       double n1,n2,res = 0;
       double ret;
      
       
           System.out.println(
           "[+] SUMARn"+
           "[-] RESTARn"+
           "[*] MULTIPLICARn"+
           "[/] DIVIDIRn"+
           "[=] SALIRn"+
           "Ingresa una opcion:");
           
      
       op=teclado.next();
      
       System.out.println("suma ingrese el primer numero");
       n1= teclado.nextInt();
         
        while (!op.equals("=")){
    	   switch(op){
    	     
        
         case "+": 
         
         System.out.println("ingrese el segundo numero");
         n2= teclado.nextInt();
          res = suma(n1,n2);
          n1=res;
          System.out.println("el resultado es: "+res);
         break;
         
         case "-":
        
             System.out.println("ingrese el segundo numero");
             n2= teclado.nextInt();
             res=resta(n1,n2);
             System.out.println("el resultado es: "+res);
             break;
             
         case "*":
         
             System.out.println("ingrese el segundo numero");
             n2= teclado.nextInt();
             res=multi(n1,n2);
             System.out.println("el resultado es: "+res);
             break;
             
         case "/":
         
             System.out.println("ingrese el segundo numero");
             n2= teclado.nextInt();
             res=division(n1,n2);
             System.out.println("el resultado es: "+res);
             break;
             
      
    	   }
    	   System.out.println(
    	           "[+] SUMARn"+
    	           "[-] RESTARn"+
    	           "[*] MULTIPLICARn"+
    	           "[/] DIVIDIRn"+
    	           "[=] SALIRn"+
    	           "Ingresa una opcion:"); 
    	   op=teclado.next();
        }
        
        System.out.println("el resultado es: "+res);
        
}     


public static double suma(double x, double y){
	double res;
res=x+y;
return res;
}
public static double resta(double x, double y){
	double res;
res=x-y;
return res;
}
public static double multi(double x, double y){
	double res;
res=x*y;
return res;
}
public static double division(double x, double y){
	double res; 
res=x/y;
return res;
}
}
el problema es que la calculadora tiene que mostrar el resultado con las operaciones acumuladas, por ejemplo el resultado tiene que mostrar esto: 54+5-6*8/2+9=44, alguno sabe como se hace eso?
 #461421  por Slek
 21 Dic 2014, 15:32
Buenas,
disculpa la tardanza, espero que te siga siendo útil.

Propongo una solución basada en prioridades para los operadores. El objetivo es asociar operadores por la izquierda, respetando las prioridades de cada operador. La idea es la siguiente:
Leer dos operadores consecutivos para determinar la acción a realizar.

Es decir, si los operadores tienen la misma prioridad, podemos reducir la expresión (asociando a la izquierda)
Ej: 5+3-2 puede interpretarse como (5+3)-2, y es equivalente a la reducción 8-2

Si los operadores tiene distinta prioridad, existen dos casos posibles:

p1 < p2
En este caso, hay que reducir el segundo operador antes que el primero. Para ello, se almacena en una pila para posponer su evaluación.
Ej: 5+2*3 puede interpretarse como 5+(2*3) (en este caso todavía no podemos reducir la expresión 2*3 porque no sabemos si le siguen operadores con mayor prioridad)

p1 > p2
En este caso, podemos reducir la expresión del primer operador, pero debemos asociar a la izquierda, es decir, evaluar con los datos almazenados en la pila.
Ej: 5*2+3 puede interpretarse como (5*2)+3, y es equivalente a 10+3 (en este caso la pila está vacía, no hay operadores anteriores)

Así, por ejemplo, la expresión propuesta (54+5-6*8/2+9) se evaluaría de la siguiente manera:
((54+5)-((6*8)/2))+9
que conduce al resultado esperado 44, puesto que la resta y división son asociativos por la izquierda (la suma y multiplicación cumple la propiedad asociativa por ambos lados)

A continuación propongo un código a modo de ejemplo implementando esta idea, utilizando número naturales como la entrada y números enteros como salida. El algoritmo puede contener errores, no he hecho pruebas exahustivas.
// By Slek
	public static int eval(String exp) {
		// By Slek

		byte[] str = exp.getBytes();
		int index = 0;

		Stack<Integer> stack = new Stack<Integer>();

		// Initialization
		int n1 = 0;
		int x1 = 0;

		while ((index < str.length) && (x1 = getInt(str[index++])) >= 0) {
			n1 *= 10;
			n1 += x1;
		}

		if (index == str.length)
			return n1;

		boolean loop;
		
		int p1, p2;

		while (index < str.length) {
			
			int n2 = 0;
			int x2 = 0;
			
			// Parser
			while ((index < str.length) && (x2 = getInt(str[index++])) >= 0) {
				n2 *= 10;
				n2 += x2;
			}
			
			do{
				loop = false;
				
				p1 = getPriority(x1);
				p2 = getPriority(x2);

				if (p1 == p2) {
					// Reduction
					n1 = eval(n1, x1, n2);
					x1 = x2;
				} else if (p1 < p2) {
					// Associate Right
					stack.push(n1);
					stack.push(x1);
					n1 = n2;
					x1 = x2;
				} else { // p1 > p2
					// Associate Left
					n2 = eval(n1, x1, n2);
					if (!stack.isEmpty()){
						x1 = stack.pop();
						n1 = stack.pop();
						loop = true;
					} else {
						n1 = n2;
						x1 = x2;
					}
				}
			} while (loop);
		}

		return n1;
	}

	public static int eval(int n1, int x, int n2) {
		switch (x) {
		case -5:
			return n1 + n2;
		case -3:
			return n1 - n2;
		case -6:
			return n1 * n2;
		case -1:
			return n1 / n2;
		default:
			return 0;
		}
	}

	public static int getInt(byte b) {
		return (b - 48);
	}

	public static int getPriority(int x) {
		switch (x) {
		case -5:
		case -3:
			return 1;
		case -6:
		case -1:
			return 2;
		default:
			return 0;
		}
	}
Ejemplo de uso:
public static void main(String[] args) {
	String test = "54+5-6*8/2+9";
	// ((54+5)-(6*8)/2))+9

	System.out.println(eval(test));
}
Un saludo!