题目
请写一个整数计算器,支持加减乘三种运算和括号。 示例1 输入:“1+2” 返回值:3 示例2 输入:“(2*(3-4))*5” 返回值:-10 示例3 输入:“3+2*3*4-1” 返回值:26
思路
经典的中缀表达式求值。常用思路,将其转为后缀表达式(后缀表达式的特点:遇到运算符则将前两个数拿出来运算,便于计算机计算),边转边求值。 读到左括号 ( 较为特殊,读到左括号时直接入栈, 本题中运算符优先级:左括号或栈顶为空、乘、加减 、右括号。 读到右括号时一直出栈直到一个左括号出栈。
算法步骤
遍历字符串,当 遍历到的字符是数字 时,直接将其压入数字栈。 否则,当 遍历到的字符是运算符 时,判断字符,直到字符串读完: 若符号栈为空,则直接将其压入符号栈。 若符号栈非空,则判断符号栈栈顶的运算符优先级: 若 遍历到的运算符符号的优先级 > 符号栈栈顶元素的优先级,或符号栈空,则将读取的运算符压入符号栈。 若 遍历到的运算符符号的优先级 ≤ 符号栈栈顶元素的优先级,则将其出栈,并从数字栈弹出两个元素进行该运算,先弹出的为右操作数,后弹出的为左操作数,将结果压入数字栈。 最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算,重复该操作直到符号栈空。 符号栈为空后,弹出数字栈栈顶元素作为结果。 返回数值站栈顶元素作为最终结果。
int solve ( string s) { stack< char > sign; stack< int > num; for ( int i = 0 ; i < s. length ( ) ; i++ ) { if ( s[ i] >= '0' && s[ i] <= '9' ) { int rear = i; while ( ( rear + 1 ) < s. length ( ) && s[ rear + 1 ] >= '0' && s[ rear + 1 ] <= '9' ) { rear++ ; } int n = 0 ; for ( int j = rear; j >= i; j-- ) { n += ( s[ j] - '0' ) * pow ( 10 , ( rear - j) ) ; } i = rear; num. push ( n) ; } else if ( s[ i] == '(' || s[ i] == '*' || sign. size ( ) == 0 ) { sign. push ( s[ i] ) ; } else if ( s[ i] == '+' || s[ i] == '-' ) { while ( 1 ) { if ( sign. size ( ) == 0 ) break ; if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } else if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else { break ; } } sign. push ( s[ i] ) ; } else if ( s[ i] == ')' ) { while ( 1 ) { if ( sign. size ( ) == 0 ) { break ; } else if ( sign. top ( ) == '(' ) { sign. pop ( ) ; break ; } else if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } } } } while ( sign. size ( ) != 0 ) { if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } } return num. top ( ) ;
}
实例
# include <iostream>
# include <stack>
using namespace std; int solve ( string s) { stack< char > sign; stack< int > num; for ( int i = 0 ; i < s. length ( ) ; i++ ) { if ( s[ i] >= '0' && s[ i] <= '9' ) { int rear = i; while ( ( rear + 1 ) < s. length ( ) && s[ rear + 1 ] >= '0' && s[ rear + 1 ] <= '9' ) { rear++ ; } int n = 0 ; for ( int j = rear; j >= i; j-- ) { n += ( s[ j] - '0' ) * pow ( 10 , ( rear - j) ) ; } i = rear; num. push ( n) ; } else if ( s[ i] == '(' || s[ i] == '*' || sign. size ( ) == 0 ) { sign. push ( s[ i] ) ; } else if ( s[ i] == '+' || s[ i] == '-' ) { while ( 1 ) { if ( sign. size ( ) == 0 ) break ; if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } else if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else { break ; } } sign. push ( s[ i] ) ; } else if ( s[ i] == ')' ) { while ( 1 ) { if ( sign. size ( ) == 0 ) { break ; } else if ( sign. top ( ) == '(' ) { sign. pop ( ) ; break ; } else if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } } } } while ( sign. size ( ) != 0 ) { if ( sign. top ( ) == '+' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 + n2) ; } else if ( sign. top ( ) == '-' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 - n2) ; } else if ( sign. top ( ) == '*' ) { sign. pop ( ) ; int n2 = num. top ( ) ; num. pop ( ) ; int n1 = num. top ( ) ; num. pop ( ) ; num. push ( n1 * n2) ; } } return num. top ( ) ;
} int main ( )
{ string mys = "1+3*(5+2)" ; cout<< mys<< "=" << solve ( mys) << endl; return 0 ;
}