C语言数据结构之逆波兰表达式求值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1135004584/article/details/79357267

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。


eg:1+1

逆波兰表达式:1 1 +

eg:1+(2-1)*3

逆波兰表达式:1 2 1 - 3 * +


实现截图:


Stack.h

扫描二维码关注公众号,回复: 4987186 查看本文章


#ifndef _STACK_H_
#define _STACK_H_

#include <stdbool.h>
#define STACK_INIT_SIZE 100 //栈控件初始化大小
#define STACK_INCREMENT 10 //栈控件增量

typedef struct{
    void * base;//栈底
    void * top;//栈顶
    int stackSize;//当前已经分配的存储空间
    int elementLength;
}SqStack;

typedef enum{
    FAILED,SUCCESS
}Status;

Status initStack(SqStack * pStack,int elength);

void destroyStack(SqStack * pStack);
void clearStack(SqStack * pStack);//将栈置空
bool stackIsEmpty(SqStack * pStack);
int stackLength(const SqStack * pStack);
void * getTop(SqStack * pStack);
void push(SqStack * pStack,void *data);//压栈
void pop(SqStack * pStack,void *data);//出栈,若不空删除栈顶元素并将其值返回

void * get(SqStack * pStack,int i);//获取栈的第i个位置的元素

/**
 * 输出栈中每个元素,如果direction为正则从头到尾输出,反之从尾到头输出.
 * @param pStack
 * @param pfun
 * @param direction
 */
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction);

#endif


Stack.c

#include <malloc.h>
#include <memory.h>
#include <assert.h>
#include "Stack.h"

Status initStack(SqStack * pStack,int elength)
{

    pStack->base = malloc((size_t) (elength * STACK_INIT_SIZE));
    if(!pStack->base)//如果分配内存失败
        return FAILED;

    pStack->elementLength = elength;
    pStack->top = pStack->base;
    pStack->stackSize = STACK_INIT_SIZE;

    return SUCCESS;
}

void destroyStack(SqStack * pStack)
{
    if(pStack)
    {
        free(pStack->base);
        pStack->base = NULL;
        pStack->top = NULL;
        pStack->stackSize = 0;
    }

}

void clearStack(SqStack * pStack)//将栈置空
{
    if(pStack)
        pStack->top = pStack->base;
}

bool stackIsEmpty(SqStack * pStack)
{
    if(pStack)
    {
        if(pStack->top == pStack->base)
            return true;
        else
            return false;
    }

    return false;
}

/**
 * 返回栈当前长度
 * 用栈顶减去栈底除以单个元素大小即可.
 * @param pStack
 * @return
 */
int stackLength(const SqStack * pStack)
{
    return (int) (pStack->top - pStack->base)/pStack->elementLength;
}

void * getTop(SqStack * pStack)
{
    if(pStack->top == pStack->base)
        return NULL;
    else
        return pStack->top;
}

void push(SqStack * pStack,void *data)//压栈
{

    if((pStack->top - pStack->base)/pStack->elementLength >= pStack->stackSize)
    {
        pStack->base =
                realloc(pStack->base,
                        (size_t) ((pStack->stackSize + STACK_INCREMENT)*pStack->elementLength));

        assert(pStack->base != NULL);
        pStack->top = pStack->base+pStack->stackSize*pStack->elementLength;
        pStack->stackSize += STACK_INCREMENT;
    }
    memcpy(pStack->top, data, (size_t) pStack->elementLength);

    pStack->top = pStack->top+pStack->elementLength;
}

void pop(SqStack * pStack,void *data)//出栈,若不空删除栈顶元素并将其值返回
{
    if(pStack->top != pStack->base)
    {
        if(data)
            memcpy(data,pStack->top,(size_t)pStack->elementLength);
        pStack->top -= pStack->elementLength;
    }
}


void * get(SqStack * pStack,int i)//获取栈的第i个位置的元素
{
    void * pn = NULL;

    if(stackLength(pStack) != 0)
        pn = &pStack->base[i];

    return pn;
}


/**
 *
 * @param pStack
 * @param pfun
 * @param direction 遍历方向
 * @param isHex 是否是16进制
 */
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction)
{
    void * pd = NULL;
    if(direction > 0)
    {
        pd = pStack->base;

        while(pd < pStack->top)
        {
            pfun(pd);
            pd += pStack->elementLength;
        }
    }else{
        pd = pStack->top;

        while(pd > pStack->base)
        {
            pd -= pStack->elementLength;
            pfun(pd);
        }
    }

}


main2.c


#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "Stack.h"

#define MAXBUFFER 10

int main(void)
{

    SqStack stack;
    initStack(&stack,sizeof(double));
    printf("请输入逆波兰表达式,输入#结束输入.\n");

    char c;
    char buffer[MAXBUFFER];
    double a,b;
    int i = 0;

    scanf("%c",&c);
    while(c != '#')
    {
        while(isdigit(c) || c == '.')
        {
            buffer[i] = c;
            i++;

            if(i >= MAXBUFFER)
            {
                fprintf(stderr,"数字长度超出范围自动跳过!\n");
                return -1;
            }

            scanf("%c",&c);

            if(c == ' ')
            {
                buffer[i] = '\0';
                a = atof(buffer);
                push(&stack,&a);
                i = 0;
                break;
            }
        }

        switch(c)
        {
            case '+':
                pop(&stack,&a);
                pop(&stack,&b);
                a+=b;
                push(&stack,&a);
                break;
            case '-':
                pop(&stack,&a);
                pop(&stack,&b);
                a-=b;
                push(&stack,&a);
                break;
            case '*':
                pop(&stack,&a);
                pop(&stack,&b);
                a*=b;
                push(&stack,&a);
                break;
            case '/':
                pop(&stack,&a);
                pop(&stack,&b);

                if(b != 0){
                    a/=b;
                    push(&stack,&a);
                }else
                {
                    fprintf(stderr,"发生错误,除数为0!\n");
                    return -1;
                }
                break;
        }
        scanf("%c",&c);
    }

    pop(&stack,&a);
    printf("计算结果为:%lf\n",a);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/a1135004584/article/details/79357267