您的位置:首页 > 其它

5-20 表达式转换 (25分)

2015-10-10 13:42 405 查看
5-20 表达式转换 (25分)

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含
+
-
*
\
以及左右括号
()
,表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +


时间限制:400ms
内存限制:64MB
代码长度限制:16kB
判题程序:系统默认
作者:DS课程组
单位:浙江大学

题目判定

/* http://pta.patest.cn/pta/test/15/exam/4/question/827 5-20 表达式转换   (25分)

中缀表达式(也就是一般的算式)
1 stack在遍历的时候不能使用sta1._Get_container().at(i) , 使用队列queue deque可以替换stack
2 还有此题耗费了不少时间(数据刚开始用了double 发现始终不对,改成了string)
3 另外 关于括号() 这个位置 操作比较的繁琐
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <set>
#include <iterator>
#include <vector>
#include <algorithm>
#include <string.h>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <sstream>
#include <iterator>

using namespace std;

#define N 22

int opeprior(char c) // 运算符优先级,值越大优先级越高
{
if (c == '+' || c == '-')
return 1;
if (c == '*' || c == '/')
return 2;
if (c == '(')
return 3;
return -1;
}

double str2double(string s) // string转double
{
stringstream ss;
double d;
ss << s;
ss >> d;
return d;
}

struct mydata // string是数值,char为符号
{
string d;
char c;
mydata(string _d = 0, char _c = '0') :d(_d), c(_c){}
};

int main()
{
//freopen("in.txt", "r", stdin);
char s
;
while (scanf("%s", s) != EOF)
{
int len = strlen(s);
int i, j;
queue<mydata> sta1;
stack<char> sta2;
string stmp = "";
for (i = 0; i < len; i++)
{
char c = s[i];
if ((c >= '0' && c <= '9') || c == '.')
{
stmp +=c;
}
else if (c == '+' || c == '-')
{
if (i == 0)
{
stmp += c;
}
else{
if (stmp != ""){
//double dt = str2double(stmp);
mydata dd(stmp, '0');
stmp = "";
sta1.push(dd);
}
else{
if (!sta2.empty() && sta2.top() == '(')
{
if (c == '-')
{
stmp += c;
continue;
}
else if (c == '+'){
continue;
}
}
}
if (sta2.empty()){
sta2.push(c);
continue;
}
char copeUp = sta2.top();
if (opeprior(c) > opeprior(copeUp) && copeUp != '(')
{
sta2.push(c);
}
else if (copeUp == '('){
sta2.push(c);
}
else{
while (!sta2.empty() && opeprior(copeUp) >= opeprior(c))
{
mydata dd("0", copeUp);
sta1.push(dd);
sta2.pop();
if (sta2.empty())
break;
copeUp = sta2.top();
if (copeUp == '(')
{
break;
}
}
sta2.push(c);
}
}
}
else if (c == '*' || c == '/')
{
if (stmp != ""){
//double dt = str2double(stmp);
mydata dd(stmp, '0');
stmp = "";
sta1.push(dd);
}
if (sta2.empty()){
sta2.push(c);
continue;
}
char copeUp = sta2.top();
if (opeprior(c) > opeprior(copeUp) && copeUp != '(')
{
sta2.push(c);
}
else if (copeUp == '('){
sta2.push(c);
}
else{
while (!sta2.empty() && opeprior(copeUp) >= opeprior(c))
{
mydata dd("0", copeUp);
sta1.push(dd);
sta2.pop();
if (sta2.empty())
break;
copeUp = sta2.top();
if (copeUp == '(')
{
break;
}
}
sta2.push(c);
}

}
else if (c == '(')
{
sta2.push(c);
}
else if (c == ')'){
if (stmp != "")
{
mydata dd(stmp, '0');
stmp = "";
sta1.push(dd);
}
// 找到第一个( 全部出栈
char cope = sta2.top();
if (cope == '(')
{
sta2.pop();
continue;
}
while (cope != '(')
{
mydata dd("0", sta2.top());
sta1.push(dd);
sta2.pop();
cope = sta2.top();
if (cope == '(')
{
sta2.pop();
}
}
}
}

if (stmp != "") // 输入的表达式最后一个为处理的数据
{
mydata dd(stmp, '0');
stmp = "";
sta1.push(dd);
}
while (!sta2.empty()) // 最后栈中剩余的符号
{
char copeUp = sta2.top();
mydata dd("0", copeUp);
sta1.push(dd);
sta2.pop();
if (sta2.empty())
break;
}

int size2 = sta1.size();
bool flag = false;
// 结果输出
while (!sta1.empty())
{
mydata st = sta1.front();
if (st.c == '+' || st.c == '-' || st.c == '*' || st.c == '/')
{
if (!flag){
printf("%c", st.c);
flag = true;
}
else{
printf(" %c", st.c);
}
}
else{
if (!flag){
cout << st.d;
flag = true;
}
else{
cout << " " << st.d;
}
}
sta1.pop();
}
printf("\n");
}// while
return 0;
}


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <queue>
#include <stack>

using namespace std ;

int opePriority(char c)
{
if(c == '+' || c == '-')
return 0 ;
if(c == '*' || c == '/')
return 1 ;
if(c == '(')
return 2 ;
return -1 ;
}

struct mydata // string是数值,char为符号
{
string d;
char c;
mydata(string _d = 0, char _c = '0') :d(_d), c(_c){}
};

int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
char s[21] ;
gets(s);
int i;
string stmp ;
stack<char> opeSta ;
deque<mydata> dataSta ;
for(i = 0;s[i] != '\0';i++)
{
char c = s[i];
if( (c >= '0' && c <= '9') ||  c == '.')
{
stmp += c ;
}else{
if(stmp != "")
{
mydata dt(stmp ,'0');
dataSta.push_back(dt);
stmp = "";
}else{
//  -1+3*(-2) 类似这种表示式的处理
if(!opeSta.empty() && opeSta.top() == '(')
{
if (c == '-') {
stmp += c;
continue;
}
else if (c == '+'){
continue;
}
}
if(opeSta.empty() && dataSta.empty())
{
if (c == '-') {
stmp += c;
continue;
}
else if (c == '+'){
continue;
}
}
}
int pri = opePriority(c);
if(opeSta.empty())
{
opeSta.push(c);
}else{
if(pri != -1)
{
char opeTop = opeSta.top() ;
int pri_opeTop = opePriority(opeTop) ;
// 当前符号的优先级大 或者 栈顶是左括号
if(pri > pri_opeTop || opeTop == '(')
{
opeSta.push(c) ; // 入栈
}else{
// 先出 后进
opeTop = opeSta.top() ;
pri_opeTop = opePriority(opeTop) ;
while(pri <= pri_opeTop && !opeSta.empty())
{
opeSta.pop();

mydata dt("" ,opeTop);
dataSta.push_back(dt);

if(!opeSta.empty())
{
opeTop = opeSta.top() ;
pri_opeTop = opePriority(opeTop) ;
}
if(opeTop == '(') // 遇到 左括号停止
break;
}
opeSta.push(c);
}
}else{ // 是右括号 则opeSta 出栈到 左括号位置
char opeTop = opeSta.top() ;
while(opeTop != '(')
{
opeSta.pop();

mydata dt("" ,opeTop);
dataSta.push_back(dt);

opeTop = opeSta.top() ;
}
opeSta.pop() ;
}
}
}
}
if(stmp != "")
{
mydata dt(stmp ,'0');
dataSta.push_back(dt);
}
while(!opeSta.empty())
{
mydata dt("" ,opeSta.top());
dataSta.push_back(dt);

opeSta.pop();
}
// 结果输出
cout << dataSta.front().d ;
dataSta.pop_front();
while(!dataSta.empty())
{
string num = dataSta.front().d;
char ope = dataSta.front().c ;

if(ope == '0')
{
cout << " " << num ;
}else{
printf(" %c",ope);
}
dataSta.pop_front();
}
printf("\n");
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: