Isragca Isragca - 3 months ago 13
Java Question

Stacks Array infix operation

I need to write a program that evaluates a math expession in infix notation using parenthesis,the first line of the input is the number of expressions to evaluate. The problem is that I don't know how to make that the first line of input make the number of total expressions. Also the input need to be

(2*(3+5))
but the code I make only accept
(" 2 * (3 + 5)")
, I already use the replaceAll() for remove the space but the correct of the run is incorrect.Sorry for the spanish comments.

Input
2
((7+(3*5))+(14/2))
((2+5)*3)


Output that I want
29
21


import java.util.Stack;
import java.util.Scanner;

public class Stacks
{
public static int evaluarop(String string)
{
//Pasar el string a un arreglo de Char;
// index nombre del arreglo de Chars para saber en que char va.
char[] index = string.toCharArray();

// Crea un Stack 'numero' de tipo Integer con la clase Stack<E>
Stack<Integer> numero = new Stack<Integer>();

// Crea un Stack 'simbolo' de tipo Character con la clase Stack<E>
Stack<Character> simbolo = new Stack<Character>();

//For inicia el bucle
for (int i = 0; i < index.length; i++)
{
// Index = char actual
// Index en la posición actual es un espacio en blanco, pasar al siguiente char.
if (index[i] == ' ')
continue;

// Si el index actual es un numero ponerlo en el stack de numero.
// Si el index es un char del 0 al 9
if (index[i] >= '0' && index[i] <= '9')
{
// If pregunta si el index es un char del 0 al 9
// StringBuffer() = construye un string de almacenamiento sin caracteres
// y con capacidad inicial de 16 caracteres
StringBuffer sbuf = new StringBuffer();
// Si es un numero formado por mas de un digito.
while (i < index.length && index[i] >= '0' && index[i] <= '9')
sbuf.append(index[i++]);
// Inserta en el Stack de numeros.
// ParseInt pasa el String y lo retorna como un entero.
numero.push(Integer.parseInt(sbuf.toString()));
}

// Si el index acutal es '(', hacer push a stack simbolo.
else if (index[i] == '(')
simbolo.push(index[i]);

// Si el index actual es ')' prepara para hacer la operacion.
else if (index[i] == ')')
{
// While peek para ver el simbolo actual hasta que no sea un (.
while (simbolo.peek() != '(')
// Hace el push al resultado de la operacion.
// operandop() hace la operacion correspondiente al char de simbolo correspondiente.
// Numero.pop() agarra el numero para operar.
numero.push(operando(simbolo.pop(), numero.pop(), numero.pop()));
// Quita del arreglo el simbolo ya utilizado.
simbolo.pop();
}

// Si el index actual es un simbolo de operación.
else if (index[i] == '+' || index[i] == '-' || index[i] == '*' || index[i] == '/')
{
// While si el char hasta arriba del Stack simbolo tiene la misma o mayor
// jerarquia de operaciones que el char de simbolo.
// Aplica el operador en la cima del Stack simbolo
// Mientras que el Stack de simbolo no esta vacio hace lo anterior.
while (!simbolo.empty() && prioridad(index[i], simbolo.peek()))
numero.push(operando(simbolo.pop(), numero.pop(), numero.pop()));

// Hace Push al char actual del Stack simbolo
simbolo.push(index[i]);
}
}

while (!simbolo.empty())
numero.push(operando(simbolo.pop(), numero.pop(), numero.pop()));
// Stack numero contiene el resultado, hace pop() para regresarlo.
return numero.pop();
}

// Si la operacion2 es de mayor importancia que operacion1; regresa true
public static boolean prioridad(char operacion1, char operacion2)
{
if (operacion2 == '(' || operacion2 == ')')
return false;
if ((operacion1 == '*' || operacion1 == '/') && (operacion2 == '+' || operacion2 == '-'))
return false;
else
return true;
}

// Aplica la operación correspondiente mediante un switch con el caracter de simbolo.
// Regresa el resultado.
public static int operando(char operacion, int num1, int num2)
{
switch (operacion)
{
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
}
return 0;
}

// Main probador
public static void main(String[] args)
{
System.out.println("Operaciones con stacks.");
Scanner sc = new Scanner(System.in);
//int totalop = sc.nextInt();
//for(int i = 0; i < totalop;i++)
//{
System.out.println("Op: ");
//String string = sc.nextLine();
//System.out.println(Stacks.evaluarop(string));
System.out.println(Stacks.evaluarop("10+2*6"));
System.out.println(Stacks.evaluarop("10 + 2 * 6"));
}
}

Answer

I think i found your problem.

On line 32 (if the first import is on line 1) you read all the numbers you find until another character that is not a number is found.

Inside you increment the counter i, that is giving you the position of the character currently under consideration, which after the loop is the next character to consider (like you read all the 10 and i is the + sign in your first test.

But, before you can examine it, you have to go through the outer for loop again, with is going to increment the i again.

To understand this, add

System.out.println("Examining char "+i+" :"+index[i]);

on line 18 (https://ideone.com/NxyECc for the already compiled and working thing)

it will give you the following output:

Operaciones con stacks.
Op: 
Examining char 0 :1
Examining char 3 :2
Examining char 5 :6
6
Examining char 0 :1
Examining char 3 :+
Examining char 4 : 
Examining char 5 :2
Examining char 7 :*
Examining char 8 : 
Examining char 9 :6
22

As you can see, in the first case it is not examining none of the operations because the two subsequent i++ (the one inside the while and the one of the for) makes you lose them.

A simple i-- after the while on line 32 (in the ideone link it is commented, you can just fork and uncomment it) will make everything work.

Comments