• 后缀表达式求值


    题目要求:

    后缀表达式求值:建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。
    输入格式:
    在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。
    输出格式:
    输出后缀式计算结果,所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过109。如果执行除法时出现分母为零的非法操作,则在一行中输出:Error: X/0,X是当时的分子。如果后缀表达式中运算符多了或者少了,则在一行中输出:Expression Error: X,X是当时栈顶元素。
    输入样例1:5 -2 + 3 * #  输出:9
    输入样例2:5 -2 2 + / #   输出:Error: 5/0
    输入样例3:5 -1 3 + / - * #   输出Expression Error: 2

    框架结构:

    1. //用于存放操作数的栈
    2. int OPND[100];
    3. int top=0;
    4. //运算操作
    5. int operate(int a,char operate,int b)
    6. //计算表达式函数,如果出现错误的表达式返回false,表达式正确返回true,并且表达式的值最终会存在栈里。
    7. bool caculate(string s);
    8. int main()
    9. {
    10. string s;
    11. top=0;
    12. getline(cin,s);//可以接受空格
    13. if(caculate(s))
    14. {
    15. cout<<"表达式的值为:"<<OPND[0];
    16. }
    17. }

    栈的一些操作:

    其实不用特意的写这些函数,下面几个操作都可以用一个语句完成,写成函数是为了方便阅读

    1. //栈的操作
    2. void push(int num)
    3. {
    4. OPND[top++]=num;
    5. }
    6. int pop()
    7. {
    8. return OPND[--top];
    9. }
    10. int GetTop()
    11. {
    12. return OPND[top-1];
    13. }

    将两个数进行一次操作的函数:

    1. int operate(int a,char operate,int b)
    2. {//不出现/0的情况
    3. int ans;
    4. if(operate=='+')
    5. ans=a+b;
    6. else if(operate=='-')
    7. ans=a-b;
    8. else if(operate=='*')
    9. ans=a*b;
    10. else
    11. ans=a/b;
    12. return ans;
    13. }

    计算表达式的函数:

    我是一个字符一个字符扫描的,有的人习惯将表达式的string串以空格分成多个string串,对每个string串扫描,这样也可以。

    1. bool caculate(string s)
    2. {
    3. int a,b,num=0,i=0;
    4. int sign=1;//记录数字符号
    5. char thea;
    6. while(s[i]!='#')
    7. {
    8. if(s[i]>='0'&&s[i]<='9')
    9. {//遇到数字开始构造
    10. num=10*num+s[i]-'0';
    11. }
    12. if(s[i]=='-'&&s[i+1]>='0'&&s[i+1]<='9')
    13. {//'-'后面跟着数字,说明遇到了负数 ,标记符号
    14. sign=-1;
    15. }
    16. else if(s[i]=='+'||s[i]=='-'||s[i]=='/'||s[i]=='*')
    17. {
    18. if(top==0)
    19. {//没有操作数
    20. cout<<"Expression Error: No operand!";
    21. return false;
    22. }
    23. else if(top<2)
    24. {//操作数不够
    25. cout<<"Expression Error: "<<OPND[top-1];
    26. return false;
    27. }
    28. b=pop();
    29. a=pop();
    30. if(b==0&&s[i]=='/')
    31. {//除数为零的情况
    32. cout<<"Expression Error: "<<a<<"/"<<b;
    33. return false;
    34. }
    35. int ans=operate(a,s[i],b);//先抛出的做第二操作数
    36. push(ans);
    37. }
    38. else if(s[i-1]>='0'&&s[i-1]<='9'&&s[i]==' ')
    39. {//当前字符是空格并且前面字符是数字
    40. num*=sign;
    41. push(num);
    42. num=0;
    43. sign=1;
    44. }
    45. i++;
    46. }
    47. if(top>1)
    48. {//扫描结束后栈里的数大于一个,说明表达式有误
    49. cout<<"Expression Error: "<<OPND[top-1];
    50. return false;
    51. }
    52. return true;
    53. }

    代码:

    1. #include<iostream>
    2. using namespace std;
    3. int OPND[100];
    4. int top=0;
    5. //栈的操作
    6. void push(int num)
    7. {
    8. OPND[top++]=num;
    9. }
    10. int pop()
    11. {
    12. return OPND[--top];
    13. }
    14. int GetTop()
    15. {
    16. return OPND[top-1];
    17. }
    18. int operate(int a,char operate,int b)
    19. {//不出现/0的情况
    20. int ans;
    21. if(operate=='+')
    22. ans=a+b;
    23. else if(operate=='-')
    24. ans=a-b;
    25. else if(operate=='*')
    26. ans=a*b;
    27. else
    28. ans=a/b;
    29. return ans;
    30. }
    31. bool caculate(string s)
    32. {
    33. int a,b,num=0,i=0;
    34. int sign=1;//记录数字符号
    35. char thea;
    36. while(s[i]!='#')
    37. {
    38. if(s[i]>='0'&&s[i]<='9')
    39. {//遇到数字开始构造
    40. num=10*num+s[i]-'0';
    41. }
    42. if(s[i]=='-'&&s[i+1]>='0'&&s[i+1]<='9')
    43. {//'-'后面跟着数字,说明遇到了负数 ,标记符号
    44. sign=-1;
    45. }
    46. else if(s[i]=='+'||s[i]=='-'||s[i]=='/'||s[i]=='*')
    47. {
    48. if(top==0)
    49. {//没有操作数
    50. cout<<"Expression Error: No operand!";
    51. return false;
    52. }
    53. else if(top<2)
    54. {//操作数不够
    55. cout<<"Expression Error: "<<OPND[top-1];
    56. return false;
    57. }
    58. b=pop();
    59. a=pop();
    60. if(b==0&&s[i]=='/')
    61. {//除数为零的情况
    62. cout<<"Expression Error: "<<a<<"/"<<b;
    63. return false;
    64. }
    65. int ans=operate(a,s[i],b);//先抛出的做第二操作数
    66. push(ans);
    67. }
    68. else if(s[i-1]>='0'&&s[i-1]<='9'&&s[i]==' ')
    69. {//当前字符是空格并且前面字符是数字
    70. num*=sign;
    71. push(num);
    72. num=0;
    73. sign=1;
    74. }
    75. i++;
    76. }
    77. if(top>1)
    78. {
    79. cout<<"Expression Error: "<<OPND[top-1];
    80. return false;
    81. }
    82. return true;
    83. }
    84. int main()
    85. {
    86. string s;
    87. top=0;
    88. getline(cin,s);//可以接受空格
    89. // cout<<s;
    90. if(caculate(s))
    91. {
    92. cout<<"表达式的值为:"<<OPND[0];
    93. }
    94. }

  • 相关阅读:
    视频去水印 部分源码(包含部分php与go)有需要可以联系我
    【排序算法】常见排序算法总结
    HTTP协议数字报错(详细说明)
    视频共享融合赋能平台LntonCVS统一视频接入平台数字化升级医疗体系
    打开cmd的方式和常用Dos命令
    7.ProTable必填的查询表单
    jeesite vue教程
    面试秘籍 | 软件测试必备的mysql数据库技术
    ABeam中国2022社招 | ABeam旗下德硕管理咨询(上海) 热招岗位虚位以待
    WPF 截图工具
  • 原文地址:https://blog.csdn.net/m0_73441691/article/details/133967695