Red de conocimiento informático - Aprendizaje de código fuente - Procedimiento estándar de evaluación de expresiones de la versión del lenguaje c de la estructura de datos

Procedimiento estándar de evaluación de expresiones de la versión del lenguaje c de la estructura de datos

Idea: expresión infija-sufijo expresión-evaluación

Código de referencia:

# include & ltiostream & gt

# include & ltcstdio & gt

# include & ltvector & gt

# include & ltcstdlib & gt

# include & ltcstring & gt

# include & lt iteración Dispositivo & gt

# include & ltAlgorithm& gt

//Implementación de la matriz de pila, el tamaño de la matriz es fijo.

Plantilla<TClass>

ClassStack

{

Privado:

t * s; la matriz (parte inferior de la pila)

size_t N; //Apunta al primer bloque libre en la parte superior de la pila.

const size _ t size//El tamaño de la pila es fijo.

Público:

stack(size_t n): tamaño(n)

{

s = new T[n];/ /puede generar una excepción.

n = 0; //Establece el puntero superior de la pila

}

~Stack()

{

Eliminar[]s;

}

bool vacío() constante

{

return N = = 0;

}

Constante booleana completa()

{

retorno N = = tamaño

}

Push no válido (objeto constante T y amp)

{

if (full())

{

throws " Error: ¡La pila está llena!";

}

s[n++]= objeto;

}

tpop()< / p>

{

if (empty())

{

Lanza "Error: ¡la pila está vacía!";

}

return s[-N];

}

T peek() constante

{

if (empty())

{

Lanza "Error: ¡la pila está vacía!";

}

return s[ N-1];

}

Amigos std::ostream &operator<<(std::ostream&sistema operativo, const stack& ltT & gt& ampstk)

{

for(tamaño _ t I = 0; i & ltstk.

n;i++)

{

STD::cout & lt;& ltSTK s[I]& lt;& lt" ";

}<. /p>

Regresar al sistema operativo;

}

};

//Implementación de la lista vinculada de pila

Plantilla & clase ltT y gt

Pila de clases

{

Privado:

nodo de estructura typedef

{

Elemento de prueba;

Nodo * siguiente;

nodo(T x, nodo *t = NULL): elemento(x), siguiente(t) {}< / p>

} *Enlace;

Encabezado del enlace; //Apunta al primer objeto válido en la parte superior de la pila

Público:

Pila (el tamaño es n)

{

head = NULL

}

~STACK() //También puedes usar pop para eliminar, pero la eficiencia es baja.

{

Enlace t = encabezado

mientras (t!=null)

{

Enlace; d = t;

t = t-& gt;Siguiente;

Eliminar d;

}

}

constante bool vacía()

{

return head = = NULL

}

Constante booleana completa()

{

Devuelve falso

}

Inserción no válida (objeto constante T y amp)

{

cabeza = nuevo nodo(objeto, cabeza);

}

tpop()

{

if (vacío ())

{

Lanza "Error: ¡la pila está vacía!";

}

t v = head- >item ;

enlace t = head->next;

eliminar encabezado;

head = t;

Regresar v;

}

T peek() constante

{

si (vacío())

{

Lanza "Error: pila vacía!";

}

Devuelve encabezado ->item;

}

Amigos std::ostream&operator<<(STD::ostream&operator&operator<<const stack<T>&stk)

{

for(link t = STK . head; t!= NULLt = t -& gt; siguiente)

{

STD::cout & lt; & ltt->; elemento & lt& lt" ";

}

Volver al sistema operativo;

}

};

//Las expresiones infijas se convierten en expresiones postfijas, que solo admiten sumas, restas, multiplicación y división, y el operando es 1 decimal entero no negativo.

char * infijo 2 postfix(const char * infix, char *postfix)

{

const size_t N = strlen(infix);

if (N == 0 || sufijo == NULL)

{

Sufijo de retorno;

}

pila<char> opcode(N); //operador de ahorro de pila.

for(size_t I = 0;i<n;i++)

{

cambiar(infix[i])

{

Case '(': //Ignora el corchete izquierdo directamente.

Break;

Case ')': //Operador pop

p>

* postfix++ = código de operación . pop();

* postfix++ = "";

Pausa;

Caso "+":

Caso '-':

Caso ' * ':

Caso "/":

opcode . Dividir por operador

;

Valor predeterminado:

If(is digit(infix[I])//Si es un número, salida directa.

{

* postfix++ = infijo[I];

* postfix++ = ""; }

}

Devuelve sufijo;

}

//Convierte expresión de sufijo en expresión infija, solo admite suma, resta y multiplicación. y división, el operando es 1 entero decimal no negativo

char * postfix 2 infix (const char * postfix, char *infix)

{

const size_t N = strlen(suffix);

if (N == 0 || infix == NULL)

{

Devolviendo infix

}

* infix = ' \ 0//Inicializa la cadena de salida para que esté vacía

STD::vector & lt;

//Inicializa y coloca todos los caracteres válidos en el contenedor

for(size_t I = 0;i<n;i++)

{

si(es dígito(postfix[I])| | postfix[I]= = '+'

|| sufijo[i] == '- ' ||Sufijo[i] == '* ' ||Sufijo[i] == '/')

{

v . push _ back(STD::string( 1, postfix[I]);

}

}

//Procesar cada operador

for(STD:: vector & lt; STD::string & gt; *Iterador b = v . comenzar(); b & ltv final(); b++)

{

if(* b = = "+" | | * b = = "- " | | * b = = " * " | | * b = = "/)

{

copiar( v.begin(), v.end(), STD: :ostream_iterator<STD::string>(std::cout,"\n"));

STD: :cout <<"-"<<STD::endl;

std::string opcode = *(b);

STD::string op rand 1 = *(b-2);

STD::string op rand 2 = *(b-1);

b = v.erase(b - 2, b +1); //Elimina las tres expresiones originales y reemplázalas por otras nuevas.

b = v.insert(b, STD::string(")+op rand 1+opcode+op rand 2+STD::string(")");

}

}

for(STD::vector & lt; STD::string & gt; *Iterador b = v . comenzar(); b & ltv . end() ; b++)

{

strcat(infix, (*b).c_str());

}

Devuelve infijo <; /p>

}

//Calcula el valor de la expresión postfix, solo admite expresiones con operandos no negativos.

int postfix _ eval (const char * postfix. )

{

const size_t N = strlen(postfix);

Si (N == 0)

{

Devuelve 0;

}

Pila & ltint & gt operando (N); //La pila guarda el operando

for(size_t). I = 0;i<n;i++)

{

interruptor(sufijo[i])

{

int op1, op2

Caso "+":

op 1 = operando . pop();

op2 = operando . push(op 1+op2);

Break;

Caso '-':

op 1 = pop();

.

op2 = operando . pop();

operando .push(op 1-op2);

Pausa;

p>

Caso ' * ':

op 1 = operando . pop();

op2 = operando .

operando . );

Break;

Caso "/":

op 1 = pop();

op2 = operando. pop();

operando . push(op 1/op2);

Romper

Valor predeterminado:

if(es dígito(postfix[I])//Realiza funciones similares a atoi().

{

operando . push(0);

mientras (isdigit(postfix[i]))

{

operando . push(10 * operando . pop()+postfix[i++]-' 0 ');

}

I-; >}

}

STD::cout & lt;& ltoperand& lt& ltSTD::endl;//Emite el contenido de la pila

}< / p>

Return operand . pop();

}

//Este programa demuestra cómo convertir expresiones postfijas y expresiones infijas entre sí, y cómo usar la pila. para evaluar expresiones postfix.

//Dirección de conversión: org _ infix-& gt; suffix-& gt; infix

int main(int argc, const char *argv[])

{

//const char * org _ infix = "(5 *(9+8)*(4 * 6))+7)" //Sección 4.3

const char * org _ infix = "(5 *(9 * 8)+(7 *(4+6)))" //Ejercicio 4.12

STD::cout & lt; "Expresión infija original:"

char * const postfix = new char[strlen(org_infix)+1];

infix2postfix(org_infix, postfix);

STD::cout & lt;& lt"Expresión Postfix:"

char * const infix = new char[strlen(postfix)+1];

postfix2infix(sufijo, infijo) ;

STD::cout & lt;& lt"Expresión infija:"

STD::cout & lt;& lt" cálculo El resultado es: "

STD::cout & lt;& lt" El resultado del cálculo es: "

Eliminar [] infijo;

Eliminar [] sufijo;

Regresar 0;

}