• 1358:中缀表达式值(expr)


    【题目描述】

    输入一个中缀表达式(由0-9组成的运算数、加+减-乘*除/四种运算符、左右小括号组成。注意“-”也可作为负数的标志,表达式以“@”作为结束符),判断表达式是否合法,如果不合法,请输出“NO”;否则请把表达式转换成后缀形式,再求出后缀表达式的值并输出。

    注意:必须用栈操作,不能直接输出表达式的值。

    【输入】

    一行为一个以@结束的字符串。

    【输出】

    如果表达式不合法,请输出“NO”,要求大写。

    如果表达式合法,请输出计算结果。

    【输入样例】

    1+2*8-9@

    【输出样例】

    8

    思路: 

    检查:
    1.括号匹配
    2.开头的负号和‘(’后的负号前都要加零
    3.两个符号连在一起就是错的。除非是)后有符号和(前有符号

    计算:
    1.中缀转后缀

    方法:
    a.遇到操作数,直接放入后缀表达式的队列中
    b.遇到运算符,首先把符号栈中,从栈顶开始循环把优先级大于等于它的符号放入后缀表达式。然后把符号存入符号栈
    c.遇到'(',直接入栈
    d.遇到')',把符号栈中的符号从栈顶开始循环加入后缀表达式中,直到遇见'(',直接弹出'('不加入

    2.计算后缀表达式

    代码:

     

    1. #include
    2. using namespace std;
    3. string a;
    4. bool check()
    5. {
    6. //括号匹配
    7. int t=0;
    8. for(int i=0;ilength()-1;i++)
    9. {
    10. if(a[i]=='(')t++;
    11. if(a[i]==')'){
    12. if(t>0)t--;
    13. else{
    14. return false;
    15. }
    16. }
    17. }
    18. if(t!=0)return false;
    19. //在-前面插入0
    20. for(int i=0; ilength()-1;i++)
    21. {
    22. if(i==0&&a[i]=='-')
    23. a='0'+a;
    24. else if(a[i]=='-'&&a[i-1]=='(')//右括号后面的负号
    25. a.insert(i,"0");//在第i位置插入0
    26. }
    27. //除了首位的'('与末尾的')',其余情况首尾不能为运算符
    28. for(int i=0;ilength()-1;i++)
    29. {
    30. if(!(a[i]>='0'&&a[i]<='9')&&!(a[i+1]>='0'&&a[i+1]<='9')){
    31. if(a[i]==')'&&a[i+1]=='(')return false;
    32. else if(!(a[i]==')'||a[i+1]=='('))return false;
    33. }
    34. }
    35. return true;
    36. }
    37. void jisuan()
    38. {
    39. //中缀转后缀
    40. map<char, int> p;
    41. p['+']=p['-']=1;
    42. p['*']=p['/']=2;
    43. p['(']=0;
    44. queue<char> h;//后缀
    45. stack<char> f;//符号
    46. for(int i=0;ilength()-1;i++)
    47. {
    48. if(a[i]>='0'&&a[i]<='9'){
    49. h.push(a[i]);
    50. if(!(a[i+1]>='0'&&a[i+1]<='9')){
    51. h.push(' ');
    52. }
    53. }
    54. else{
    55. if(a[i]=='('){
    56. f.push(a[i]);
    57. }
    58. else if(a[i]==')'){
    59. while(f.top()!='(')
    60. {
    61. h.push(f.top());
    62. f.pop();
    63. }
    64. f.pop();
    65. }
    66. else
    67. {
    68. while(f.size()&&p[f.top()]>=p[a[i]]){
    69. h.push(f.top());
    70. f.pop();
    71. }
    72. f.push(a[i]);
    73. }
    74. }
    75. }
    76. while(f.size()){
    77. h.push(f.top());
    78. f.pop();
    79. }
    80. //求后缀
    81. stack<int> s;
    82. int t=0;
    83. while(h.size()){
    84. char b=h.front();
    85. h.pop();
    86. int c=0,d=0;
    87. int sum=0;
    88. if(b==' '){
    89. s.push(t);
    90. t=0;
    91. }
    92. else if(b>='0'&&b<='9')
    93. {
    94. t=t*10+int(b-'0');
    95. }
    96. else{
    97. d=s.top();
    98. s.pop();
    99. c=s.top();
    100. s.pop();
    101. if(b=='+')sum=c+d;
    102. else if(b=='-')sum=c-d;
    103. else if(b=='*')sum=c*d;
    104. else sum=c/d;
    105. s.push(sum);
    106. }
    107. }
    108. cout<top()<
    109. }
    110. int main()
    111. {
    112. cin>>a;
    113. if(check()){
    114. jisuan();
    115. }
    116. else cout<<"NO"<
    117. return 0;
    118. }

  • 相关阅读:
    买卖股票的最佳时机含冷冻期
    技术管理进阶——扎心了!老板问我:你们技术部和外包团队有什么区别?
    小小购物车案例(V3)
    觉非科技发布【轻地图高速NOA智驾方案】|地平线,觉非科技,MobileDrive超捷生态协作实现技术落地
    Java高性能实体类转换工具MapStruct
    STM32 - SPI硬件外设
    常见面试题-MySQL软删除以及索引结构
    猿创征文|Camunda工作流
    Open CASCADE学习|为什么由Edge生成Wire不成功?
    小程序使用npm以及常用的移动端UI插件
  • 原文地址:https://blog.csdn.net/Zero_979/article/details/126139267