良い兄弟が私に式計算のプログラム、メインのエクササイズスタックを尋ねました。しかし、彼は私に質問をしました。複数の桁で計算すると、正規表現の変換が機能しないようです。つまり、従来のプログラムでは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