算术表达式的转换
題目描述
小明在學習了數據結構之后,突然想起了以前沒有解決的算術表達式轉化成后綴式的問題,今天他想解決一下。 因為有了數據結構的基礎小明很快就解出了這個問題,但是他突然想到怎么求出算術表達式的前綴式和中綴式呢?小明很困惑。聰明的你幫他解決吧。輸入
輸入一算術表達式,以\'#\'字符作為結束標志。(數據保證無空格,只有一組輸入)輸出
輸出該表達式轉換所得到的前綴式 中綴式 后綴式。分三行輸出,順序是前綴式 中綴式 后綴式。示例輸入
a*b+(c-d/e)*f#示例輸出
+*ab*-c/def a*b+c-d/e*f ab*cde/-f*+
前綴規律:
1)? 設立操作符棧OPTR,結果棧RESULT;
2) 從右向左遍歷,若當前字符是操作數,則直接發送給RESULT棧;
3)? 若當前運算符的優先數高于等于棧頂運算符,則進OPTR棧;
4)? 否則,退出棧頂運算符發送給RESULT棧;
5)?? “)” 對它之前后的運算符起隔離作用,“(”可視為自相應右括弧開始的表達式的結束符。(即讀到右括號時總是將它壓入OPTR棧中,讀到左括號時,將靠近棧頂的第一個右括號上面的運算符全部依次彈出,送至RESULT棧后,再丟棄右括號。 )
后綴規律:
1)? 設立操作符棧;
2) 若當前字符是操作數,則直接發送給后綴式;
3)? 若當前運算符的優先數高于棧頂運算符,則進棧;
4)? 否則,退出棧頂運算符發送給后綴式;
5)?? “(” 對它之前后的運算符起隔離作用,“)”可視為自相應左括弧開始的表達式的結束符。(即讀到左括號時總是將它壓入棧中,讀到右括號時,將靠近棧頂的第一個左括號上面的運算符全部依次彈出,送至輸出隊列后,再丟棄左括號。?)
?
?#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int cmp(char c)//運算符的優先級;
{
? ? if(c == '+'||c == '-') return 1 ;
? ? if(c == '*'||c == '/') return 2 ;
? ? if(c == '(') ?return 3 ;
? ? if(c == ')') ?return 4 ;
? ? return 0 ;
}
void Qianzhui(char a[])//前綴式的獲得;數組模擬棧;
{
? ? int top2 = -1, top3=-1;
? ? int l = strlen(a);
? ? char stack2[100], stack3[100];
? ? for(int i = l-2; i >= 0; i--)//從后往前讀入;
? ? {
? ? ? ? if(a[i] >= 'a'&&a[i]<= 'z')//是英文則進數組stack3;
? ? ? ? {
? ? ? ? ? ? stack3[++top3] = a[i];
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? if(top2 == -1||stack2[top2] == ')'|| a[i] == ')')//進數組stack2的條件;
? ? ? ? ? ? {
? ? ? ? ? ? ? ? stack2[++top2] = a[i];
? ? ? ? ? ? }
? ? ? ? ? ? else if(a[i] == '(')
? ? ? ? ? ? {
? ? ? ? ? ? ? ? while(stack2[top2] != ')')
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? stack3[++top3] = stack2[top2--];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? top2--;
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(cmp(a[i]) < cmp(stack2[top2]))//比較運算優先順序;
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? stack3[++top3]= stack2[top2--];
? ? ? ? ? ? ? ? ? ? i++;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? stack2[++top2] = a[i];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? while(top2 != -1)//將數組stack2的所有元素挪進stack3;
? ? {
? ? ? ? stack3[++top3] = stack2[top2--];
? ? }
? ? for(int i = top3; i >= 0; i--)//逆序輸出數組的所有元素;
? ? ? ? printf("%c", stack3[i]);
? ? printf("\n");
}
void Zhongzhui(char a[])//中綴式的獲得;
{
? ? for(int i = 0; a[i] != '#'; i++)
? ? {
? ? ? ? if(a[i] !='(' &&a[i] != ')')
? ? ? ? ? ? printf("%c", a[i]);
? ? }
? ? printf("\n");
}
void Houzhui(char a[])//后綴式的獲得;
{
? ? int top1 = 0;
? ? char stack1[100] ;
? ? for(int i = 0; a[i] != '#'; i++)
? ? {
? ? ? ? if(a[i] >= 'a'&&a[i] <= 'z')//是字母則直接輸出;
? ? ? ? {
? ? ? ? ? ? printf("%c", a[i]) ;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? if(top1 == 0)//數組空則直接進數組;
? ? ? ? ? ? {
? ? ? ? ? ? ? ? top1++ ;
? ? ? ? ? ? ? ? stack1[top1] = a[i] ;
? ? ? ? ? ? }
? ? ? ? ? ? else if(cmp(a[i]) > cmp(stack1[top1]))//優先運算的比較;
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(cmp(a[i]) == 4)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? while(stack1[top1] != '(')
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? printf("%c", stack1[top1--]);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? top1-- ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? top1++ ;
? ? ? ? ? ? ? ? ? ? stack1[top1] = a[i];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(stack1[top1] != '(')
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? printf("%c", stack1[top1]) ;
? ? ? ? ? ? ? ? ? ? stack1[top1] = a[i] ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? top1++ ;
? ? ? ? ? ? ? ? ? ? stack1[top1] = a[i] ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? while(top1 != 0)//數組所有元素的輸出;
? ? {
? ? ? ? printf("%c", stack1[top1]) ;
? ? ? ? top1-- ;
? ? }
? ? printf("\n") ;
}
int main()
{
? ? char a[1005];
? ? scanf("%s",a);
? ? Qianzhui(a);//前綴式;
? ? Zhongzhui(a);//中綴式;
? ? Houzhui(a);//后綴式;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define stackmax 10000
#define stacknum 10000
typedef int elemtype;
typedef struct
{
? ? elemtype *base;
? ? elemtype *top;
? ? int stacksize;
} sqstack;
int initstack(sqstack &s)//棧的初始化;
{
? ? s.base = (elemtype *)malloc(stackmax * sizeof(elemtype));
? ? if(!s.base) exit(0);
? ? s.top = s.base;
? ? s.stacksize = stackmax;
}
char push(sqstack &s, char e)//進棧;
{
? ? if(s.top - s.base > s.stacksize)
? ? {
? ? ? ? s.base = (elemtype *)realloc(s.base,(s.stacksize+stacknum) * sizeof(elemtype));
? ? ? ? if(!s.base) exit(0);
? ? ? ? s.top = s.base + s.stacksize;
? ? ? ? s.stacksize += stacknum;
? ? }
? ? *s.top++=e;
}
int pop(sqstack &s)//出棧;
{
? ? if(s.top==s.base) return 0;
? ? s.top--;
? ? return 1;
}
char gettop(sqstack &s)//獲得棧頂元素;
{
? ? if(s.top == s.base) return 0;
? ? char e = *(s.top-1);
? ? return e;
}
int stackempty(sqstack &s)//判斷棧是否為空;
{
? ? if(s.top == s.base)
? ? ? ? return 1;
? ? else
? ? ? ? return 0;
}
int cmp(char c)//用于比較優先級
{
? ? if (c=='+'||c=='-')
? ? ? ? return 1;
? ? if (c=='*'||c=='/')
? ? ? ? return 2;
? ? if (c=='(')
? ? ? ? return 3;
? ? if (c==')')
? ? ? ? return 4;
}
char lasttranslate(sqstack &s, char c[])//后綴式的獲得;
{
? ? int n=strlen(c);
? ? int i;
? ? for(i=0; i<n; i++)
? ? {
? ? ? ? if (c[i]>='a'&&c[i]<='z')
? ? ? ? ? ? printf("%c", c[i]);
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? if(c[i]!='#')
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(stackempty(s))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? push(s, c[i]);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if(cmp(c[i])>cmp(gettop(s)))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? if(c[i]==')')
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? while(gettop(s)!='(')
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? printf("%c", *(s.top-1));
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pop(s);
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? pop(s);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? push(s, c[i]);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? if(gettop(s)=='(')
? ? ? ? ? ? ? ? ? ? ? ? ? ? push(s, c[i]);
? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? printf("%c", gettop(s));
? ? ? ? ? ? ? ? ? ? ? ? ? ? pop(s);
? ? ? ? ? ? ? ? ? ? ? ? ? ? push(s,c[i]);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
char pretranslate(sqstack &s1, sqstack &s2, char c[])//前綴式的獲得;
{
? ? int n=strlen(c);
? ? int i;
? ? for(i=n-2; i>=0; i--)//逆序讀入;
? ? {
? ? ? ? if (c[i]>='a'&&c[i]<='z')
? ? ? ? ? ? push(s1, c[i]);
? ? ? ? else
? ? ? ? ? ? if(stackempty(s2))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? push(s2, c[i]);
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(cmp(c[i])>=cmp(gettop(s2)))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if(c[i]=='(')
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? while(gettop(s2)!=')')
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? push(s1, *(s2.top-1));
? ? ? ? ? ? ? ? ? ? ? ? ? ? pop(s2);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? pop(s2);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? push(s2, c[i]);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if(gettop(s2)==')')
? ? ? ? ? ? ? ? ? ? ? ? push(s2, c[i]);
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? push(s1, gettop(s2));
? ? ? ? ? ? ? ? ? ? ? ? pop(s2);
? ? ? ? ? ? ? ? ? ? ? ? push(s2,c[i]);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? }
}
void putstack1(sqstack &s)//棧內所有元素的輸出;
{
? ? while(s.top > s.base)
? ? {
? ? ? ? printf("%c", *(s.top-1));
? ? ? ? s.top--;
? ? }
}
void putstack2(sqstack &s)
{
? ? while(s.top > s.base)
? ? {
? ? ? ? printf("%c", *(s.base));
? ? ? ? s.base++;
? ? }
}
char midtranlate(char c[])//中綴式的獲得;
{
? ? int n=strlen(c), i;
? ? for(i=0;i<n;i++)
? ? {
? ? ? ? if(c[i]!='('&&c[i]!=')'&&c[i]!='#')
? ? ? ? printf("%c", c[i]);
? ? }
}
int main()
{
? ? char c[110];
? ? sqstack s;//定義棧;
? ? sqstack s1, s2;
? ? initstack(s);//初始化棧;
? ? initstack(s1);
? ? initstack(s2);
? ? scanf("%s", c);
? ? pretranslate(s1, s2, c);//前綴式
? ? putstack2(s2);//前綴式的輸出;
? ? putstack1(s1);
? ? printf("\n");
? ? midtranlate(c);//中綴式的輸出;
? ? printf("\n");
? ? lasttranslate(s, c);//后綴式;
? ? putstack1(s);//棧可能不為空
? ? return 0;
}
總結