问题分析
上一节我们已经知道该如何将中缀表达式转为后缀表达式(传送门 ),这里我们将直接将实际计算一个表达式,比如
99
+
87
×
98
99+87\times98
9 9 + 8 7 × 9 8 #,要求表达式结尾以’#‘结束 ;
实现方法
得到后缀表达式
这里我们用队列 存储后缀表达式结果; 另一方面值得注意的是这里的操作数是不知几位的数字,在转后缀的要值得注意 (小树我自己踩过的坑 ),解决方法是在遇到操作符前将操作数的每一位存储在一个字符串中,在遇到操作符时,将其存储在队列中,然后将字符串清空,存储下个操作数。具体代码如下:
bool is_operator ( const char temp)
{
return temp == '+' || temp == '-' || temp == '/' || temp == '*' || temp == '(' || temp == ')' ;
}
long long level_operator ( char temp)
{
if ( temp == '+' || temp == '-' ) return 2 ;
else if ( temp == '*' || temp == '/' ) return 1 ;
else return 0 ;
}
queue< string> * Infix_convert ( string ex)
{
if ( ex. back ( ) != '#' ) ex. append ( 1 , '#' ) ;
stack< char > op;
op. push ( '#' ) ;
queue< string> * re= new queue< string> ;
string infix_ex;
for ( int i = 0 ; ex[ i] != '#' ; i++ )
{
if ( ! is_operator ( ex[ i] ) ) infix_ex. append ( 1 , ex[ i] ) ;
else if ( ex[ i] == ')' )
{
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
for ( ; op. top ( ) != '(' ; op. pop ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
}
op. pop ( ) ;
}
else
{
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
for ( ; level_operator ( op. top ( ) ) <= level_operator ( ex[ i] ) && op. top ( ) != '#' && op. top ( ) != '(' ; op. pop ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
}
op. push ( ex[ i] ) ;
}
}
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
while ( ! op. empty ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
op. pop ( ) ;
}
return re;
}
操作数字符串转为数字
long long string_to_int ( string temp)
{
int length = temp. size ( ) ;
long long re = 0 ;
for ( int i = 0 ; i < length; i++ )
{
long long pi = 1 ;
for ( int j = length - i - 2 ; j >= 0 ; j-- )
{
pi *= 10 ;
}
re += ( long long ( char ( temp[ i] ) ) - 48 ) * pi;
}
return re;
}
计算过程
在后缀表达式队列中从队首读取,操作数存储在栈中,当在队列中读取到操作符时,将栈的栈顶前两位取出计算,并将结果存储在栈中,以此往复 ,代码如下:
long long Basic_eval ( long long a, long long b, string op)
{
if ( op == "+" ) return a + b;
else if ( op == "-" ) return a - b;
else if ( op == "*" ) return a * b;
else if ( op == "/" ) return a / b;
else throw "Cann't Eval!" ;
}
long long Eval ( string ex)
{
queue< string> * ex_inf;
ex_inf = Infix_convert ( ex) ;
stack< long long > data;
for ( ; ex_inf-> front ( ) != "#" ; ex_inf-> pop ( ) )
{
if ( ! is_operator_s ( ex_inf-> front ( ) ) ) data. push ( string_to_int ( ex_inf-> front ( ) ) ) ;
else
{
long long dataB = data. top ( ) ;
data. pop ( ) ;
long long dataA = data. top ( ) ;
data. pop ( ) ;
data. push ( Basic_eval ( dataA, dataB, ex_inf-> front ( ) ) ) ;
}
}
return data. top ( ) ;
}
代码总览
# include <iostream>
# include <stack>
# include <queue>
using namespace std;
bool is_operator ( const char temp)
{
return temp == '+' || temp == '-' || temp == '/' || temp == '*' || temp == '(' || temp == ')' ;
}
bool is_operator_s ( const string temp)
{
return temp == "+" || temp == "-" || temp == "/" || temp == "*" || temp == "(" || temp == ")" ;
}
long long level_operator ( char temp)
{
if ( temp == '+' || temp == '-' ) return 2 ;
else if ( temp == '*' || temp == '/' ) return 1 ;
else return 0 ;
}
queue< string> * Infix_convert ( string ex)
{
if ( ex. back ( ) != '#' ) ex. append ( 1 , '#' ) ;
stack< char > op;
op. push ( '#' ) ;
queue< string> * re= new queue< string> ;
string infix_ex;
for ( int i = 0 ; ex[ i] != '#' ; i++ )
{
if ( ! is_operator ( ex[ i] ) ) infix_ex. append ( 1 , ex[ i] ) ;
else if ( ex[ i] == ')' )
{
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
for ( ; op. top ( ) != '(' ; op. pop ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
}
op. pop ( ) ;
}
else
{
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
for ( ; level_operator ( op. top ( ) ) <= level_operator ( ex[ i] ) && op. top ( ) != '#' && op. top ( ) != '(' ; op. pop ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
}
op. push ( ex[ i] ) ;
}
}
if ( ! infix_ex. empty ( ) )
{
re-> push ( infix_ex) ;
infix_ex. clear ( ) ;
}
while ( ! op. empty ( ) )
{
char temp[ 2 ] = { op. top ( ) , 0 } ;
re-> push ( temp) ;
op. pop ( ) ;
}
return re;
}
long long string_to_int ( string temp)
{
int length = temp. size ( ) ;
long long re = 0 ;
for ( int i = 0 ; i < length; i++ )
{
long long pi = 1 ;
for ( int j = length - i - 2 ; j >= 0 ; j-- )
{
pi *= 10 ;
}
re += ( long long ( char ( temp[ i] ) ) - 48 ) * pi;
}
return re;
}
long long Basic_eval ( long long a, long long b, string op)
{
if ( op == "+" ) return a + b;
else if ( op == "-" ) return a - b;
else if ( op == "*" ) return a * b;
else if ( op == "/" ) return a / b;
else throw "Cann't Eval!" ;
}
long long Eval ( string ex)
{
queue< string> * ex_inf;
ex_inf = Infix_convert ( ex) ;
stack< long long > data;
for ( ; ex_inf-> front ( ) != "#" ; ex_inf-> pop ( ) )
{
if ( ! is_operator_s ( ex_inf-> front ( ) ) ) data. push ( string_to_int ( ex_inf-> front ( ) ) ) ;
else
{
long long dataB = data. top ( ) ;
data. pop ( ) ;
long long dataA = data. top ( ) ;
data. pop ( ) ;
data. push ( Basic_eval ( dataA, dataB, ex_inf-> front ( ) ) ) ;
}
}
return data. top ( ) ;
}
int main ( )
{
string ex;
cout << "请输入表达式:" << endl;
cin >> ex;
cout << "=\t" << Eval ( ex) << endl;
return 0 ;
}
上一节:数据结构-栈与队列–中缀转后缀表达式