我有下面的代码,但是我需要代码来说明空格和两位数,例如,如果我输入(7-3)/(2 + 2),它应该显示为73-22 + /结果: 1.如果我输入(7-3)/(2 + 2),它应该出来7 3-2 2 + /结果1.如果我输入(22-10)/(2 + 2),它应该出来22 10 -2 2 + /结果:3
这是我的代码:
#include<stdio.h>
char stack[100];
int top = 0;
int eval_top = -1;
int eval_stack[100];
void push(char x) // Push char into stack
{
stack[top++] = x;
}
char pop() // Pop char to top of stack
{
if (top == -1)
return -1;
else
return stack[top--];
}
/* functions for evaluation of postfix expression */
// push function
void eval_push(int x) { // Find push result
eval_stack[++eval_top] = x;
}
// pop function
int eval_pop() { // Find pop result
if (eval_top == -1) {
return -1;
} else {
return eval_stack[eval_top--];
}
}
int priority(char x) // check priority order
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
// function to evaluate the postfix expression
void EvalPostfix(char postfix[]) {
int A, B;
int val;
char ch;
int i;
//find postfix
for (i = 0; postfix[i] != ')'; i++) {
ch = postfix[i];
if (isdigit(ch)) {
eval_push(ch - '0');
} else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
A = eval_pop();
B = eval_pop();
switch (ch) {
case '*':
val = B * A;
break;
case '/':
val = B / A;
break;
case '+':
val = B + A;
break;
case '-':
val = B - A;
break;
}
eval_push(val); //send value on top of stack
}
}
printf("\n Result: %d \n", eval_pop());
}
main() {
int i = 0;
char * e, x;
char postfix[100]; // store postfix for later evaluation
char exp[100];
printf("Infix expression : ");
scanf("%s", exp); // asking the user to enter the infix expression
printf("Postfix expression: ");
e = exp;
while ( * e != '\0') {
if (isalnum( * e)) { // if character is alphabet or number , it is printed
printf("%c", * e);
postfix[i++] = * e;
} else if ( * e == '(') // if it is open parenthesis, it is pushed into the stack without any priority
push( * e);
else if ( * e == ')') // if it is closed parenthesis , pop the elements in the stack and print them until the we see ( symbol
{
while ((x = pop()) != '(') {
printf("%c", x);
postfix[i++] = x;
}
} else // if character is symbol like +, -, *, / then based on their priority character is pushed if it high priority otherwise high priority symbols are popped and it is pushed
{
while (priority(stack[top]) >= priority( * e)) {
x = pop();
printf("%c", x);
postfix[i++] = x;
}
push( * e);
}
e++;
}
while (top != -1) // printing remaining elements in the stack
{
x = pop();
printf("%c", x);
postfix[i++] = x;
}
postfix[i] = ')'; // this is to add at the end for detecting end by the evaluation function
EvalPostfix(postfix);
}
答案 0 :(得分:1)
您的代码中存在一些问题
您的 pop 与您的 push 不对称, push 会增加索引,因此 pop 必须预先减少索引,因此第一个无效索引不是-1而是0:
char pop() // Pop char to top of stack
{
if (top == 0)
return -1;
else
return stack[--top];
}
如果所有测试都为假,priority 不会返回值,但是最后一个测试可能没用
在
while (priority(stack[top]) >= priority( * e))
您错过检查堆栈是否为空,必须为:
while ((top != 0) && (priority(stack[top]) >= priority( * e))) {
因为 stack 的第一个无效索引为0而不是-1
while(top!= -1)//打印堆栈中的剩余元素
必须
while (top != 0) // printing remaining elements in the stack
在制作后缀表达式时,数字之间没有分隔,例如,“ 12 + 3”变成“ 123+”,例如“ 1 + 23”,在 EvalPostfix 中,您考虑一个数字只能有一位数字(eval_push(ch - '0');
),因此您不能管理多于一位数字的数字。要管理几个数字,请在所有数字后添加一个分隔符,例如,空格为“ 12 3 +”或“ 1 23 +”,并使用 scanf 等
在所有情况下,您都不能正确编写后缀表达式,例如对于1 + 2 * 3,您将生成12 + 3 *,但它必须为123 * +
您没有检测到无效的中缀表达式
在
while (priority(stack[top]) >= priority( * e))
我错过了说顶部元素不是stack[top]
而是stack[top - 1]
,所以必须将其替换为
while ((top != 0) && (priority(stack[top - 1]) >= priority( * e))) {
加上校正1 + 2 * 3会生成正确的后缀表达式123 * +
请注意,引入函数 empty()和 tops()更为清晰,如果对堆栈的访问无效,则会显示一条消息并退出,而不是返回-1作为 char
int empty()
{
return (top == 0);
}
char tops()
{
if (top == 0) {
fputs("top() on the empty stack, abort", stderr);
exit(-1);
}
return stack[top - 1];
}
char pop() // Pop char to top of stack
{
if (top == 0) {
fputs("pop() on the empty stack, abort", stderr);
exit(-1);
}
return stack[--top];
}
还检测堆栈的可能溢出:
void push(char x) // Push char into stack
{
if (top == sizeof(stack)) {
fputs("stack overflow", stderr);
exit(-1);
}
stack[top++] = x;
}
所以现在您可以做
while (!empty() && (priority(tops()) >= priority( * e))) {
当然,其他堆栈也是一样
我需要代码来说明空格和两位数
两位数的限制性太强,只需管理任何整数即可,因为您可以使用 strtol 提取数字。您也不能使用scanf("%s", exp);
来读取完整的表达式,因为它在第一个空格处停了,请使用 fgets 。