使用堆栈进行C / C ++算术表达式求值

时间:2016-02-11 20:36:56

标签: c pointers struct

  

该代码用于使用的算术表达式评估   即使在我的代码计算表达式之后,我也遇到了分段错误。它在在线编译器上显示运行时错误...但是在离线编译器上运行时也是如此。不同操作的优先级也与在前面提到的相同。码。   有人可以帮我找出错误吗?

    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    //-------IMPLEMENTATION OF STACK USING LINK LIST--------------
    // define a structure of type struct node
    struct node
    {
        char* p;
        struct node* next;
    };
    //function to create a node for a given char
    struct node* CreateNode(char* c)
    {
    struct node* nd;
    nd = calloc(1,sizeof(struct node));
    (nd->p) = calloc(2,sizeof(char));
    *(nd->p) = *c;
    return nd;
    }
    // function to create an empty stack and returns it
     struct node* CreateEmptyStack()
    {
    struct node* new;
    new = calloc(1, sizeof(struct node));
    new = NULL;
    return new;
    }
    // function to check a given stack is empty or not
    int IsEmpty(struct node* stack)
    {
    if (stack==NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
    }
    // function to return the topmost element of stack
    char* Top(struct node* stack)
    {
    if (!IsEmpty(stack))
    {
        struct node* temp = stack;
        return temp->p;
    }
    }
    // function to push an element at top of stack
    struct node* Push(char* c ,struct node* stack)
    {
    struct node* temp = CreateNode(c);
    temp->next = stack;
    stack = temp;
    return stack;
    }
    //function to pop an element form a stack
    struct node* Pop(struct node* stack)
    {
    struct node* temp = stack;
    stack = temp->next;
    free(temp);
    return stack;
    }
    //--------algorithm to evaluate arithmetic expression------------
    // assigning outside stack priorities to  incoming characters
int OutsideStackPriority(char c)
{
    switch (c)
    {
        case '#' : return 0;
        case '+' : return 2;
        case '-' : return 2;
        case '*' : return 3;
        case '/' : return 4;
        case '^' : return 6;
        case '(' : return 7;
        case ')' : return 0;
    }
}
// assigning inside stack priorites to  different characters
int InsideStackPriority(char c)
{
    switch (c)
    {
        case '$' : return 0;
        case '+' : return 2;
        case '-' : return 1;
        case '*' : return 4;
        case '/' : return 3;
        case '^' : return 5;
        case '(' : return 0;
    }
}
// function to calculate a^b 
int power(int a, int b)
{
    int i , result=1 ;
    for (i = 1; i <= b; ++i)
    {
        result = result*a;
    }
    return b;
}
// Operate given two numbers and a given operator
// this function assumes that  there is only integer division
int Operation(int n1 , int n2 , char o)
{
    switch (o)
    {
        case '+' : return n2 + n1;
        case '-' : return n2 - n1;
        case '*' : return n2 * n1;
        case '/' : return n2 / n1; // return integer division only
        case '^' : return power(n2,n1);
    }
}
// function to determine a given char is a number or not
// here is one assumption that the given expression is valid
int IsNum(char ch)
{
    switch (ch)
    {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9': return 1;
        default : return 0;
    }
}
// function to handle overall logic of calculation 
void function(struct node* NStack , struct node* OStack)
{   
    char* i;
    char* c1 ;
    char* c2 ;
    char* c3 ;
    char* temp;
    int x=0;
    c3 = calloc(10,sizeof(char));
    char* o ;
    int n1 , n2 , n3;
    i = calloc(1,sizeof(char));
    *i = '$';
    OStack = Push(i,OStack);
    temp = Top(OStack);
    printf("%c\n",*temp);
    *i = getchar();
     printf("scanned character is %c\n",*i);
    while(x!=1)
    {
        if(IsNum(*i))
        {
            // now it is clear that i am definitely going to push the number into NStack
            NStack = Push(i,NStack);

            temp = Top(NStack);
            printf("%c\n",*temp);

            /**i = getchar();
            printf("scanned character is %c\n",*i);

            int k = 1;
            while(IsNum(*i))
            {
                NStack->p = realloc(NStack->p,(k+2)*sizeof(char));
                *(NStack->p + k) = *i;
                k++;
                *i = getchar();
                printf("scanned character is %c\n",*i);*/
            // }
        }

        // what to do when x is a operator
        // one assumption is still there i assume the incoming character is valid

        else
        {
            // now do the case analysis on what character i got
            switch (*i)
            {
                case ')': { while(*(Top(OStack)) != '(')
                            {
                                // Evaluate(NStack,OStack);
                                c1 = Top(NStack);
                                n1 = atoi(c1);
                                NStack = Pop(NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);

                                c2 = Top(NStack);
                                n2 = atoi(c2);
                                NStack = Pop(NStack);

                                // temp = Top(NStack);
                                // printf("%c\n",*temp);

                                o = Top(OStack);
                                n3 = Operation(n1,n2,*o) ;
                                OStack = Pop(OStack);

                                sprintf(c3,"%d",n3);
                                NStack = Push(c3,NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);

                            }
                            OStack = Pop(OStack);
                          }

                case '#' : { while(*(Top(OStack)) != '$')
                            {
                                // Evaluate(NStack,OStack
                                c1 = Top(NStack);
                                n1 = atoi(c1);
                                NStack = Pop(NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);

                                c2 = Top(NStack);
                                n2 = atoi(c2);
                                NStack = Pop(NStack);

                                // temp = Top(NStack);
                                // printf("%c\n",*temp);

                                o = Top(OStack);
                                n3 = Operation(n1,n2,*o) ; 
                                OStack = Pop(OStack);

                                sprintf(c3,"%d",n3);
                                NStack = Push(c3,NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);
                            }

                            x=1;
                            printf("%s\n",Top(OStack));
                            OStack = Pop(OStack) ;
                           }

                default  : { while(InsideStackPriority(*(Top(OStack))) >= OutsideStackPriority(*i))
                            {
                                // Evaluate(NStack,OStack);
                                c1 = Top(NStack);
                                n1 = atoi(c1);
                                NStack = Pop(NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);

                                c2 = Top(NStack);
                                n2 = atoi(c2);
                                NStack = Pop(NStack);

                                //temp = Top(NStack);
                                //printf("%c\n",*temp);

                                o = Top(OStack);
                                n3 = Operation(n1,n2,*o) ; 
                                OStack = Pop(OStack);

                                sprintf(c3,"%d",n3);
                                NStack = Push(c3,NStack);

                                temp = Top(NStack);
                                printf("%c\n",*temp);

                            }
                            OStack = Push(i,OStack);
                          } 
            }
        }
        if(x==0)
        {
            *i = getchar();     
            printf("scanned character is %c\n",*i);
        }
    }
    arkdown and HTML are turned off in code blocks:
    <i>This is // char* ans = Top(NStack);
    // printf("%s\n",ans);

    // NStack = Pop(NStack);
    // free(NStack);
    // free(OStack);
}
int main()
{
    struct node* NStack = CreateEmptyStack();
    struct node* OStack = CreateEmptyStack();
    function(NStack,OStack);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

我想也许你没有在输入中处理换行符:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400d87 in function (NStack=0x0, OStack=0x602090) at b1.c:260
260                                     printf("%c\n",*temp);

我添加了以下内容并且segfault停止了:

        switch (*i)
        {
            case ' ':
            case '\n':
                    break;

为了好玩,您可能会喜欢Dijkstra的两个堆栈算法版本,我将其作为一个示例用例:http://ccodearchive.net/info/deque.html