C語言_表示式計算_中綴轉字尾_多位數計算
阿新 • • 發佈:2020-12-29
技術標籤:C語言
之前一個好兄弟問我表示式計算的一個程式,這個主要鍛鍊棧的使用。但是他向我提出了一個問題,如果多位數計算,好像常規的表示式轉化就不靈了。即常規的程式只能計算10以下的數字,對於這個問題進行下探索。
舉個例子,常規的方法,生成的字尾表示式會是這樣的:123-*,這樣無法判斷是1還是12。也就是對多位數失效。最終確定的思路是在中綴轉字尾的過程中,對數字進行判斷:如果是多位數,則通過空格隔開。同時在後綴計算中,時刻檢查空格的存在,最後完成計算。原始碼如下:
#include<stdio.h>
#include<stdlib.h>
#include< ctype.h>
#include<string.h>
#define SIZE 100
//字元棧目的是進行中綴轉字尾
char stack[SIZE];
int top = -1;
//整數棧目的是進行字尾表示式的計算
int stack_int[SIZE];
int top_int = -1;
//字元棧操作
void push(char item)
{
if(top >= SIZE-1)
{
printf("\nStack Overflow.");
}
else
{
top = top+1;
stack[top] = item;
}
}
//字元棧操作
char pop()
{
char item ;
if(top <0)
{
printf("stack under flow: invalid infix expression");
getchar();
exit(1);
}
else
{
item = stack[top];
top = top-1;
return(item);
}
}
//整數棧操作
void push_int(int num)
{
if(top_int >= SIZE-1)
{
printf("\nStack Overflow." );
}
else
{
top_int = top_int+1;
stack_int[top_int] = num;
}
}
//整數棧操作
int pop_int()
{
int num ;
if(top_int <0)
{
printf("stack under flow: invalid infix expression");
getchar();
exit(1);
}
else
{
num = stack_int[top_int];
top_int = top_int-1;
return(num);
}
}
//funciton:判斷是否為操作符
int is_operator(char symbol)
{
if(symbol == '*' || symbol == '/' || symbol == '+' || symbol == '-')
{
return 1;
}
else
{
return 0;
}
}
//function:確定優先順序
int precedence(char symbol)
{
if(symbol == '*' || symbol == '/')
{
return(2);
}
else if(symbol == '+' || symbol == '-')
{
return(1);
}
else
{
return(0);
}
}
//function:中綴表示式轉字尾表示式,結果存於postfix_exp形參中
void InfixToPostfix(char infix_exp[], char postfix_exp[])
{
int i, j;
char item;
char x;
push('(');
strcat(infix_exp,")");
i=0;
j=0;
int tag = 0;
item=infix_exp[i];
while(item != '\0')
{
if(item == '(')
{
push(item);
}
else if( isdigit(item) || isalpha(item))
{
//when meet a digit, judge if the number is bigger than 10
//if so, add ' ' before it and ' ' after it
//use tag as a symbol to add the first ' '
char next = infix_exp[i+1];
while (isdigit(next))
{
if (tag == 0)
{
postfix_exp[j++] = ' ';
tag = 1;
postfix_exp[j++] = item;
i++;
item = next;
next = infix_exp[i+1];
}
else
{
postfix_exp[j++] = item;
i++;
item = next;
next = infix_exp[i+1];
}
}
//when tag equals to 1, it means a number bigger than 10 appears
if (tag == 1)
{
tag = 0;
postfix_exp[j++] = item;
postfix_exp[j++] = ' ';
item = next;
i++;
continue;
}
postfix_exp[j] = item;
j++;
}
else if(is_operator(item) == 1)
{
x=pop();
while(is_operator(x) == 1 && precedence(x)>= precedence(item))
{
postfix_exp[j] = x;
j++;
x = pop();
}
push(x);
push(item);
}
else if(item == ')')
{
x = pop();
while(x != '(')
{
postfix_exp[j] = x;
j++;
x = pop();
}
}
else
{
printf("\nInvalid infix Expression.\n");
getchar();
exit(1);
}
i++;
item = infix_exp[i];
}
if(top>0)
{
printf("\nInvalid infix Expression.\n");
getchar();
exit(1);
}
if(top>0)
{
printf("\nInvalid infix Expression.\n");
getchar();
exit(1);
}
postfix_exp[j] = '\0';
}
//function:字尾表示式計算
long int EvalPostfix(char postfix[])
{
int i;
char ch;
int val;
int A, B;
for ( i = 0; postfix[i] != '\0'; i++)
{
ch = postfix[i];
if(isdigit(ch))
{
val = ch-'0';
push_int(val);
}
else if (ch == ' ')
{
i++;
val = 0;
ch = postfix[i];
while (ch != ' ')
{
val = val*10 + (postfix[i]-'0');
i++;
ch = postfix[i];
}
push_int(val);
}
else if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
A = pop_int();
B = pop_int();
switch(ch)
{
case '/':
val = B / A;
break;
case '*':
val = B * A;
break;
case '+':
val = B + A;
break;
case '-':
val = B - A;
break;
}
push_int(val);
}
}
return pop_int();
}
int main()
{
char infix[SIZE], postfix[SIZE];
int value;
printf("ASSUMPTION: The infix expression contains single letter variables and single digit constants only.\n");
printf("\nEnter Infix expression : ");
gets(infix);
InfixToPostfix(infix,postfix);
printf("Postfix Expression: ");
puts(postfix);
value = EvalPostfix(postfix);
printf("Result of expression evaluation : %d", value);
system("pause");
return 0;
}
計算結果如下:
輸入中綴表示式為:10-6*(12-8/4)+3