• 利用栈进行表达式的求值


      1 #include <stdio.h>
    2 #include <string.h>
    3 #include <stdlib.h>
    4 #include <ctype.h>
    5 #include <stack>
    6 usingnamespace std;
    7
    8 stack<float> OperandStack;
    9 stack<char> OperatorStack;
    10
    11 char priority[]={'(', ')', '', '+', '-', '', '*', '/'};
    12
    13 int GetPriority(char ch, char top)
    14 {//这里用了点小技巧,通过在priority数组中添加多余的字符,可以仅通过相减来简化优先级的判断
    15 int a, b;
    16 for(int i =0; i <8; i++)
    17 {
    18 if( ch == priority[i] )
    19 a = i;
    20 if( top == priority[i] )
    21 b = i;
    22 }
    23 if( a - b <=1)
    24 return0;
    25 else
    26 return1;
    27 }
    28
    29 float compute(float p, float q, char c)
    30 {
    31 switch(c)
    32 {
    33 case'+':
    34 return p+q;
    35 case'-':
    36 return p-q;
    37 case'*':
    38 return p*q;
    39 case'/':
    40 return p/q;
    41 }
    42
    43 }
    44
    45 float ComputeResult(char suffix[])
    46 {
    47 float f, op1, op2, tmp;
    48 char*t = strtok(suffix, "");
    49 while( t != NULL )
    50 {
    51 if( isdigit(t[0]) )
    52 {//将字符串转化为浮点数
    53 f = atof(t);
    54 OperandStack.push(f);
    55 }
    56 else
    57 {//利用栈进行计算
    58 op2 = OperandStack.top();
    59 OperandStack.pop();
    60 op1 = OperandStack.top();
    61 OperandStack.pop();
    62 tmp = compute(op1, op2, t[0]);
    63 OperandStack.push(tmp);
    64 }
    65 t = strtok(NULL, "");
    66 }
    67 f = OperandStack.top();
    68 OperandStack.pop();
    69 return f;
    70 }
    71
    72 int main()
    73 {
    74 char expression[100] ="12.04 / 4 - 3 / 2 * 6 - 6 / ( 4 - 3.5 + 1 / 2 )";
    75 char suffix[100];
    76 char*ptr = suffix;
    77 int opr; //操作数
    78 char opt; //运算符
    79
    80 char*t = strtok(expression,"");
    81
    82 while( t != NULL)
    83 {
    84 if( isdigit(t[0]) )
    85 {//如果是数字则直接进入后缀表达式
    86 strcpy( ptr, t);
    87 ptr = ptr + strlen( t ) +1;
    88 *(ptr -1) ='';
    89 t = strtok(NULL, ""); //取下一个操作符或数
    90 }
    91 else
    92 {//否则就是运算符,需进行栈区的判断
    93 opt = t[0]; //取运算符
    94 if( opt =='(' ) //直接入栈
    95 {
    96 OperatorStack.push(opt);
    97 t = strtok(NULL, ""); //取下一个操作符或数
    98 }
    99 elseif( opt ==')' )
    100 {//退栈至左括号
    101 if( OperatorStack.top() !='(')
    102 {
    103 *ptr = OperatorStack.top();
    104 *(ptr +1)='';
    105 ptr +=2;
    106 OperatorStack.pop();//弹出栈顶运算符
    107 }
    108 else
    109 {
    110 OperatorStack.pop();//弹出(运算符
    111 t = strtok(NULL, ""); //取下一个操作符或数
    112 }
    113 }
    114 elseif( OperatorStack.empty() || GetPriority(opt, OperatorStack.top()) ==1 )
    115 {//如果当前运算符优先级高于栈顶 或 栈为空
    116 OperatorStack.push(opt); //入栈
    117 t = strtok(NULL, ""); //取下一个操作符或数
    118 }
    119 else
    120 {//如果低于或者等于
    121 *ptr = OperatorStack.top();
    122 *(ptr +1)='';
    123 ptr +=2;
    124 OperatorStack.pop();
    125 }
    126 }
    127 }
    128 //弹出最后栈中残留的操作符,并对suffix做结尾处理
    129 while( !OperatorStack.empty() )
    130 {
    131 *ptr = OperatorStack.top();
    132 *(++ptr) ='';
    133 ptr++;
    134 OperatorStack.pop();
    135 }
    136 *(ptr -1) ='\0';
    137 //输出后缀表达
    138 printf("%s\n", suffix);
    139 //计算结果
    140 float r = ComputeResult(suffix);
    141 printf("%f\n", r);
    142
    143 return0;
    144 }

    虽说表达式求值的算法不难理解。但是很容易出现算法细节上的认识错误。

    另外实现起来,也有众多的问题需要考虑。比如字符串和浮点数的相互转化~字符型变量与浮点变量的区别对待~还有字符串的分割处理~包括优先级的判断技巧等等~

    总之,当初俺学的时候试图实现,最后失败了。如今备考研究生,编程水平自有提升,有机会拿出来仔细写一写,复习下也不错~

  • 相关阅读:
    数据库的创建,数据的增删改查
    Ubuntu系统下查看显卡相关信息
    分布式文件系统测试方法与测试工具
    分布式存储产品的测试实践及心得
    sql注入
    web测试项目总结
    Ubuntu系统下使用Jenkins进行项目的自动构建还是项目回滚方法
    Ubuntu系统下Jenkins的git构建基本方法
    Ubuntu系统下在github中新增库的方法
    ADO.NET复习总结(2)--连接池
  • 原文地址:https://www.cnblogs.com/ShaneZhang/p/2145137.html
Copyright © 2020-2023  润新知