|
发表于 2017-8-4 19:29:38
|
显示全部楼层
这个是头文件的内容:
这个是cpp文件的内容,用的时候要包含上面头文件
- #include<iostream>
- #include<ctype.h>
- #include"Caculate.h"
- #define MAXBUFFER 50 //存放后缀表达式的最大缓冲区长度
- //中缀表达式转换为后缀表达式
- void MidtoLast(char *lastbuf)
- {
- std::cout << "请输入表达式!以#作为结束标志\n";
- midStack stack;
- InitStack(&stack); //操作符的栈初始化
- int i=0;
- char c;
- char temp;
- std::cin.get(c);
- while( '#' != c ) //输入以#作为结束符
- {
- if( isdigit(c) || c=='.' ) //对读取到的数字处理,使得数字放在一起,并且一个数字后面有一个空格
- {
- while(isdigit(c) || c=='.')
- {
- lastbuf[i++] = c;
- lastbuf[i] = ' ';
- std::cin.get(c);
- }
- i++; //保护一个数字完了之后的空格不变
- }
-
- switch( c )
- {
- case '+': // + 只要前面有非括号运算符,就应该先出栈
- if(stack.top == stack.base)
- {
- push( &stack , c );
- }
- else
- {
- do
- {
- pop( &stack , &temp );
- if( '(' == temp )
- {
- push( &stack , temp );
- }
- else
- {
- lastbuf[i++] = temp;
- lastbuf[i++] = ' ';
- }
- }while( '(' != temp && StackLen(stack));
- push( &stack , c );
- }
- break;
- case '-': // - 只要前面有非括号运算符,就应该先出栈
- if(stack.top == stack.base)
- {
- push( &stack , c );
- }
- else
- {
- do
- {
- pop( &stack , &temp );
- if( '(' == temp )
- {
- push( &stack , temp );
- }
- else
- {
- lastbuf[i++] = temp;
- lastbuf[i++] = ' ';
- }
- }while( '(' != temp && StackLen(stack));
- push( &stack , c );
- }
- break;
- case '*': // * / 需要那顺序计算,谁在先,先算谁
- if(stack.top == stack.base)
- {
- push( &stack , c );
- }
- else
- {
- pop( &stack , &temp );
- if( '*'==temp || '/'==temp )
- {
- lastbuf[i++] = temp;
- lastbuf[i++] = ' ';
- }
- else
- {
- push( &stack , temp );
- }
- push( &stack , c );
- }
- break;
- case '/': // * / 需要那顺序计算,谁在先,先算谁
- if(stack.top == stack.base)
- {
- push( &stack , c );
- }
- else
- {
- pop( &stack , &temp );
- if( '*'==temp || '/'==temp )
- {
- lastbuf[i++] = temp;
- lastbuf[i++] = ' ';
- }
- else
- {
- push( &stack , temp );
- }
- push( &stack , c );
- }
- break;
- case '(':
- push(&stack , c);
- break;
- case ')': //括号配对,知道碰见左括号
- pop( &stack , &temp );
- while( '(' != temp )
- {
- lastbuf[i++] = temp;
- lastbuf[i++] = ' ';
- pop( &stack , &temp );
- }
- break;
- }
- if( '#' != c) // 如果前面数字处理时已经读到了#,就不需要再读了
- {
- std::cin.get(c);
- }
-
- }
- while( stack.top != stack.base ) //把栈里面没有用到的符号全部弹出来
- {
- pop( &stack , &lastbuf[i++] );
- lastbuf[i++] = ' ';
- }
- lastbuf[i] = '\0'; //数组最后的结束符,防止内存泄漏
- }
- ElemType caculate(char *lastbuf)
- {
- sqStack s;
- InitStack( &s );
- int i = 0,bufcount=0;
- double d,e;
-
- char c , str[MAX_BUFFER];
- c = lastbuf[bufcount++];
- while(c != '\0')
- {
- while( isdigit(c) || c=='.') //数字处理,把连续的数字转换为一个double型
- {
- str[i++] = c;
- str[i] = '\0';
- if( i>=10 )
- {
- std::cout << "输入的数字位数过多!\n";
- }
- c = lastbuf[bufcount++];
- if( ' '== c ) // 碰见空格说明一个数字完了
- {
- d = atof(str);
- push( &s , d );
- i = 0;
- break;
- }
- }
- switch( c )
- {
- case '+':
- pop( &s , &e );
- pop( &s , &d);
- push(&s , d+e);
- break;
- case '-':
- pop( &s , &e );
- pop( &s , &d );
- push(&s , d-e);
- break;
- case '*':
- pop( &s , &e );
- pop( &s , &d );
- push(&s , d*e);
- break;
- case '/':
- pop( &s , &e );
- pop( &s , &d );
- if( e != 0 )
- {
- push(&s , d/e);
- }
- else
- {
- std::cout << "除数为0,错误!\n";
- return -1;
- }
- break;
- }
- c = lastbuf[bufcount++];
- }
- pop(&s , &d); //最终计算结果弹出到 d 中
- return d;
- }
- int main()
- {
- char lastbuf[MAXBUFFER]; //后缀表达式缓冲区
- MidtoLast(lastbuf); //中缀转后缀
-
- std::cout << "运算结果为" << caculate(lastbuf) << std::endl;
- return 0;
- }
复制代码
还有注意一下,甲鱼老师的中缀转换后缀有些问题,加减法 或者 乘除法 需要按照顺序求,就是说需要先判断站定是否有相同优先级或高优先级的运算符,如果有,就要先出栈,然后再进行压栈操作! |
|