求中缀表达式的值

第一次数据结构实验。

题目描述:求中缀表达式的值。例:( a - b ) * ( c + d )。

两种思路:一、同时开两个栈,一个栈存操作符,另一个存操作数,两个同时开工。

             二、先转化为后缀表达式,然后再计算。

我采用了第二种思路,第一种思路有点乱,没有第二种清晰。

算法是利用栈实现的:

       因为后缀表达式求值比中缀表达式求值容易,因此,先将中缀表达式转换为后缀表达式,如上式转换为后缀表达式后为:ab-cd+*。

       具体转化过程为:对表达式扫描一遍,遇到"("时,将其压栈;遇到")"时,弹栈直到遇到第一个"("为止;遇到空格,忽略;遇到其他的如"+","-","*","/",弹栈直到遇到优先级比它更低的操作符。注意:1.在弹栈时,与"+","-","*","/"相比,"("的优先级最低。2."("只有在遇到")"才弹出,在其他情况下绝对不弹出。

       转换为后缀表达式后,对后缀表达式扫描一遍,计算规则为:遇到操作数,压栈;遇到操作符,先弹出两个操作数,计算,然后将计算结果压栈。具体代码为:

#include <iostream> #include <cstdio> #include <string> #include <sstream> #include <cctype> #include <map> #define STACK_SIZE 100 //栈最大能存多少元素 using namespace std ; //功能:存储操作符 struct Stack1 { int size ; //此栈已经存了多少元素,下一个栈类似 char element[ STACK_SIZE ] ; } ; //功能:存储操作数 struct Stack2 { int size ; int element[ STACK_SIZE ] ; } ; class Calculation { public: //构造函数 Calculation( string expression ) { this->expression = expression ; answer = 0 ; operator_stack.size = operand_stack.size = 0 ; aMap[ '(' ] = 0 ; aMap[ '+' ] = 1 ; aMap[ '-' ] = 1 ; aMap[ '*' ] = 2 ; aMap[ '/' ] = 2 ; } //中缀表达式转换为后缀表达式 void midfix_to_suffix( ) { string tmp = "" ; //将表达式扫描一遍 for( int i = 0 ; i < expression.size( ) ; ) { //如果字符是数字,继续循环下去,直到把这个数字找全,最后,在数字后面加一个'.',以和别的数字区分开 if( isdigit( expression[ i ] ) ) { while( i < expression.size( ) ) { if( isdigit( expression[ i ] ) ) { tmp += expression[ i++ ] ; } else break ; } tmp += '.' ; } //如果是空格,ignore else if( expression[ i ] == ' ' ) { i++ ; continue ; } //其他的只能是操作符 else { if( expression[ i ] == '(' ) { operator_stack.element[ operator_stack.size++ ] = '(' ; i++ ; } else if( expression[ i ] == ')' ) { while( operator_stack.element[ operator_stack.size - 1 ] != '(' ) { tmp += operator_stack.element[ --operator_stack.size ] ; } operator_stack.size-- ; i++ ; } else { while( operator_stack.size > 0 ) { if( aMap[ expression[ i ] ] <= aMap[ operator_stack.element[ operator_stack.size - 1 ] ] ) { tmp += operator_stack.element[ --operator_stack.size ] ; } else break ; } operator_stack.element[ operator_stack.size++ ] = expression[ i++ ] ; } } } while( operator_stack.size > 0 ) { tmp += operator_stack.element[ --operator_stack.size ] ; } expression = tmp ; } //计算后缀表达式 void caculate( ) { int a = 0 , b = 0 , num = 0 ; for( int i = 0 ; i < expression.size( ) ; ) { if( isdigit( expression[ i ] ) ) { string tmp = "" ; while( expression[ i ] != '.' ) { tmp += expression[ i++ ] ; } i++ ; ss << tmp ; ss >> num ; ss.clear( ) ; operand_stack.element[ operand_stack.size++ ] = num ; } else { b = operand_stack.element[ --operand_stack.size ] ; a = operand_stack.element[ --operand_stack.size ] ; switch( expression[ i ] ) { case '+': operand_stack.element[ operand_stack.size++ ] = a + b ; break ; case '-': operand_stack.element[ operand_stack.size++ ] = a - b ; break ; case '*': operand_stack.element[ operand_stack.size++ ] = a * b ; break ; case '/': operand_stack.element[ operand_stack.size++ ] = a * 1.0 / b ; } i++ ; } } answer = operand_stack.element[ 0 ] ; } //得到结果 int get_answer( ) { return answer ; } private: string expression ; //表达式 int answer ; //最终结果 Stack1 operator_stack ; //存储操作符的栈 Stack2 operand_stack ; //存储操作数的栈 stringstream ss ; //字符串流,在此实现功能:将字符串转换成int类型 map< char , int > aMap ; //操作符到优先级的映射 } ; int main( ) { string expression ; while( getline( cin , expression ) ) { Calculation aCalculation( expression ) ; aCalculation.midfix_to_suffix( ) ; aCalculation.caculate( ) ; printf( "%d/n" , aCalculation.get_answer( ) ) ; } }

欢迎指正!

你可能感兴趣的:(数据结构,算法,String,struct,存储,Class)