简体   繁体   English

C语言中后缀算法的中缀

[英]Infix to Postfix Algorithm in C

I'm solve an exercise in which one of the functions has to translate infix notation to postfix notation. 我正在解决一个练习,其中一个功能必须将中缀表示法转换为后缀表示法。 Here follows my whole code 这是我的整个代码

#include<stdio.h>
#define MAX 100
char stack[MAX];
int top;
void compact(char Descomp[], char Compac[]);
void init_stack();
int push(char Elem);
int desempilha(char *Elem);
int priority(char Operator);
int arity(char Exp[], int position);
int translate_pos(char exp[], char exp_pos[]);
int main()
    {
        char Exp[MAX]; /* stores the expression read from stdin */
            char Exp_compact[MAX]; /* stores expression without spaces */
            char Exp_pos[MAX]; /* stores the expression after the translation for postfix*/
            int indicator; /* indicate if an error occurred, 0 for NO ERROR and -1 for ERROR*/
            indicator = 0;
            printf("\nType the expression: ");
            gets(Exp);
            compact(Exp, Exp_compact);
            indicator = translate_pos(Exp_compact, Exp_pos);
            puts(Exp_pos);
            return indicator;
        }
/* compact function delete spaces within the expression read from stdin */
void compact(char Descomp[], char Compac[])
        {
            int i;
            int j;
            i = 0;
            j = 0;
            while(Descomp[j] != '\0')
                {
                    if(Descomp[j] != ' ')
                        {
                            Compac[i] = Descomp[j];
                            i++;
                        }
                    j++;
                }
        }
/* initiate the stack by setting top = -1 */
void init_stack()
        {
            top = -1;
        }
/* puts the element Elem in the stack */
int push(char Elem)
        {
            if(top == MAX - 1) /* Stack is full */
                return -1;
            top++;
            stack[top] = Elem;
            return 0;
        }
/* remove the element in stack[top] and puts it in &Elem*/
int pop(char *Elem)
        {
            if(top == -1) /* stack is empty */
                return -1;
            *Elem = stack[top];
            top--;
            return 0;
        }
/* Return the priority of an operator */
int priority(char Operator)
        {
            switch(Operator)
                {
                    case '+': return 1;
                    case '-': return 1;
                    case '*': return 2;
                    case '/': return 2;
                    case '^': return 3;
                    case '(': return 4;
                    case ')': return 5;
                    default : return 0; 
                }
        }
/* returns the arity of CONSTANTS + - * / and ^, for ( an ) is merely symbolic */
int arity(char Exp[], int position)
        {
            if(priority(Exp[position]) == 1)
                {
                    if( (position == 0) || ( (priority(Exp[position - 1]) >= 1) && (priority(Exp[position - 1]) <= 3) ))
                        return 1;
                    else
                        return 2;
                }
            else if( (priority(Exp[position]) > 1) && (priority(Exp[position]) <= 4))
                return 2;
            else
                return priority(Exp[position]);
        }
/* reads an infix expression and returns postfix expression */ 
int translate_pos(char exp[], char exp_pos[])
        {
            int i;
            int j;
            int ind;
            char trash;
            i = 0;
            j = 0;
            ind = 0;
            trash = ' ';
                    init_stack();
            while(exp[i]!= '\0')
                {
                    if(arity(exp, i) == 0)
                        {
                            exp_pos[j] = exp[i];
                            j++;
                        }
                    if(arity(exp, i) == 1)
                        {
                            switch(exp[i])
                                {
                                    case '-': 
                                        {
                                            exp_pos[j] = exp_pos[i];
                                            j++;
                                        }
                                    case '+': trash = exp_pos[i];
                                }
                        }
                    if(arity(exp, i) == 2)
                        {
                            while((top != -1) && (priority(stack[top]) <= priority(exp[i])))
                                {
                                    ind = pop(&exp_pos[j]);
                                    j++;
                                }
                            ind = push(exp[i]);
                        }
                    if(priority(exp[i]) == 4)
                        {
                            ind = push(exp[i]);
                        }
                    if(priority(exp[i]) == 5)
                        {
                            while( (top != -1) && (stack[top] != '('))
                                {
                                    ind = pop(&exp_pos[j]);
                                    j++;
                                }
                            if(stack[top] == '(')
                                ind = pop(&trash);
                        }
                    i++;
                }
            while(top != -1)
                {
                    ind = pop(&exp_pos[j]);
                    j++;
                }
            return ind;

    }

The algorithm I used to translate the expression is 我用来翻译表达式的算法是

while there is token to be read;
read the token;
if token is a constant
    push it to Exp_Postfix;
if token is '('
    push it to stack
if token is ')'
    pop from the stack all symbols until '(' be find and remove '(' from the stack
if token is an operator and its arity is 2
    pop all operators with less or equal priority than the token and store then in the Exp_Postfix;
    push token to the stack;
if token is an operator and its arity is 1
    if token is '-'
          push it to Exp_postfix;
    if token is '+'
          pass to the next token;
pop all remaining symbols in the stack and push then, in order, to the Exp_Postfix;

I compiled the .c archive using 我使用

gcc -Wall archive.c -o archive

and executed it. 并执行它。 I give the expression 我表达

5+(6*9^14)

It the returned expression was 它返回的表达式是

5

I do not now if the error is in my code or in solution to the problem. 如果错误出在我的代码中或问题的解决方案中,我现在不这样做。

There are an awful lot of problems, here, for instance: 例如,这里有很多问题:

  1. compact() and translate_pos() leave Exp_compact and Exp_pos , respectively, without a terminating \\0 , so you're getting garbage printed out. compact()translate_pos()保留Exp_compactExp_pos ,而不会以\\0终止,因此您将输出垃圾。

  2. your arity() function is returning 2 for an opening parenthesis. 您的arity()函数返回2作为arity()括号。

  3. in the first switch statement of translate_pos() , you're missing break statements. translate_pos()的第一个switch语句中,您缺少break语句。

  4. Your priority comparison in translate_pos() when arity is 2 is back to front. 当arity为2时,您在translate_pos()优先级比较就回到了前面。

  5. When you're comparing operator precedence, you should treat an opening parenthesis specially, since it should have the lowest precedence when on the top of the stack. 在比较运算符优先级时,应该特别考虑一个左括号,因为它在堆栈顶部时优先级最低。

  6. You should have a lot more else keywords in translate_pos() . 您应该在translate_pos()包含更多else关键字。

  7. You're using gets() , which was always bad, and now has actually been removed from C. 您正在使用gets() ,这总是很糟糕,现在实际上已从C中删除。

I haven't exhaustively tested it, but here's a correct version that seems to work for all the test inputs I tried: 我还没有进行详尽的测试,但这是一个正确的版本,似乎适用于我尝试过的所有测试输入:

#include <stdio.h>
#include <ctype.h>
#include <assert.h>


/*  Function prototypes  */

void compact(char Descomp[], char Compac[]);
void init_stack();
int push(char Elem);
int desempilha(char *Elem);
int priority(char Operator);
int arity(char Exp[], int position);
int translate_pos(char exp[], char exp_pos[]);


/*  Stack variables  */

#define MAX 100
char stack[MAX];
int top;


int main(void) {
    char Exp[MAX];
    char Exp_compact[MAX] = {0};
    char Exp_pos[MAX] = {0};
    int indicator = 0;

    printf("\nType the expression: ");
    fgets(Exp, MAX, stdin);
    compact(Exp, Exp_compact);

    indicator = translate_pos(Exp_compact, Exp_pos);
    puts(Exp_pos);
    return indicator;
}


/* compact function delete spaces within the expression read from stdin */

void compact(char Descomp[], char Compac[]) {
    int i = 0;
    int j = 0;

    while ( Descomp[j] ) {
        if ( !isspace(Descomp[j]) ) {
            Compac[i++] = Descomp[j];
        }
        j++;
    }
}


/* initiate the stack by setting top = -1 */

void init_stack() {
    top = -1;
}


/* puts the element Elem in the stack */

int push(char Elem) {
    if (top == MAX - 1)         /* Stack is full */
        return -1;
    stack[++top] = Elem;
    return 0;
}


/* remove the element in stack[top] and puts it in &Elem*/

int pop(char *Elem) {
    if (top == -1)              /* stack is empty */
        return -1;
    *Elem = stack[top--];
    return 0;
}


/* Return the priority of an operator */

int priority(char Operator) {
    switch (Operator) {
        case '+':
            return 1;
        case '-':
            return 1;
        case '*':
            return 2;
        case '/':
            return 2;
        case '^':
            return 3;
        case '(':
            return 4;
        case ')':
            return 5;
        default:
            return 0;
    }
}


/* returns the arity of OPERATORS + - * / and ^,
 * for ( an ) is merely symbolic */

int arity(char Exp[], int position) {
    if ( priority(Exp[position]) == 1 ) {
        if ( (position == 0) ||
             ((priority(Exp[position - 1]) >= 1) &&
              (priority(Exp[position - 1]) <= 3)) ) {
            return 1;
        } else {
            return 2;
        }
    } else if ( (priority(Exp[position]) > 1) &&
                (priority(Exp[position]) <= 3) ) {
        return 2;
    } else {
        return priority(Exp[position]);
    }
}


/* reads an infix expression and returns postfix expression */

int translate_pos(char exp[], char exp_pos[]) {
    int i = 0, j = 0, ind = 0;
    char trash = ' ';

    init_stack();

    while ( exp[i] ) {
        if ( arity(exp, i) == 0 ) {
            exp_pos[j++] = exp[i];
        } else if ( arity(exp, i) == 1 ) {
            switch (exp[i]) {
                case '-':
                    exp_pos[j++] = exp[i];
                    break;
                case '+':
                    trash = exp_pos[i];
                    break;
                default:
                    assert(0);
            }
        } else if (arity(exp, i) == 2) {
            while ( (top != -1) &&
                    (priority(stack[top]) >= priority(exp[i])) &&
                    stack[top] != '(' ) {
                ind = pop(&exp_pos[j++]);
            }
            ind = push(exp[i]);
        } else if ( priority(exp[i]) == 4 ) {
            ind = push(exp[i]);
        } else if ( priority(exp[i]) == 5 ) {
            while ( (top != -1) && (stack[top] != '(') ) {
                ind = pop(&exp_pos[j++]);
            }
            if ( (top != - 1) && stack[top] == '(') {
                ind = pop(&trash);
            }
        }
        i++;
    }

    while (top != -1) {
        ind = pop(&exp_pos[j++]);
    }

    return ind;
}

Gives the following output for various test cases: 针对各种测试用例给出以下输出:

paul@local:~/src/c/postfix$ ./postfix

Type the expression: 1+2
12+
paul@local:~/src/c/postfix$ ./postfix

Type the expression: (1+2)
12+
paul@local:~/src/c/postfix$ ./postfix

Type the expression: 1+2*3
123*+
paul@local:~/src/c/postfix$ ./postfix

Type the expression: (1+2)*3
12+3*
paul@local:~/src/c/postfix$ ./postfix

Type the expression: (3+4)*4/2
34+4*2/
paul@local:~/src/c/postfix$ ./postfix

Type the expression: 5+(6*9^14)
56914^*+
paul@local:~/src/c/postfix$

I'd suggest comparing my code to yours and trying to understand the individual differences to see where you were going wrong. 我建议将我的代码与您的代码进行比较,并尝试了解各个差异,以查看您出了问题的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM