Procedimiento estándar de evaluación de expresiones de la versión del lenguaje c de la estructura de datos
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; p >
}
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
{ p>
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() p>
{
Devuelve falso
}
Inserción no válida (objeto constante T y amp)
{ p >
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; p>
}
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" ";
} p>
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])
{ p>
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;
}