栈的表达式求解 只需把printf_s(vs推荐)改成printf就可以再其他上面运行

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44065088/article/details/102585382
#include <iostream>
#include <Windows.h>
#include <string>
#include <sstream>


/***************内存检测区*********************/
#define _CRTDBG_MAP_ALLOC    //*    这个是  相当于一种开关  打开这个内存检测的开关

#include <cstdlib>   //*
#include <crtdbg.h>  //*

#ifdef  _DEBUG         //*
#ifndef DBG_NEW           //*
#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)//*
#define new DBG_NEW        //*
#endif               //*
#endif 

/***************宏定义和类型转换区*****************/
#define MAX_SIZE 128
#define STACK_S typedef

#define ELEM_TYPE int

using namespace std;

/***************结构体区*********************/
STACK_S struct stack_s {

    ELEM_TYPE* base;  // 栈底标记
    ELEM_TYPE* top;      // 栈顶元素

}stack;

static int DeBug = 1;

/***************函数定义区*********************/
bool isEmpty(stack& st);
bool isFull(stack& st);

// 1.初始化栈
bool initStack(stack& st);
// 2.入栈    e是要入栈的元素
bool pushStack(stack& st, ELEM_TYPE e);
// 3.出栈   e是要出栈的元素
bool popStack(stack& st, ELEM_TYPE& e);
// 4.销毁栈
void destroyStack(stack& st);
// 5.栈的遍历
void printStack(stack& st);
// 6.栈的长度
int stackLen(stack& st);
// 7.得到栈顶的指针
ELEM_TYPE* getTop(stack& st);

/***************有关运算式子的函数声明区*******************/

// 判断是否为 运算符
bool isOpt(int a, char *optstr, int lenth);

// 运算符优先级的比较  左大于右 就返回 >   等于的话 就放回 =   否则返回 <
char priority(char lopt, char ropt);

// 计算函数
void oper(ELEM_TYPE outvalue_1, char outopt, ELEM_TYPE outvalue_2, ELEM_TYPE& result);


/***************用户接口区*********************/
int main(void) {

    const char* str = "  16*16*(1+1)+8 =";
    char optstr[] = { '+', '-', '*', '/', '(', ')', '#', '='};

    stack opt;    // 这个是符号栈
    stack value;  // 这个式值栈

    initStack(opt);
    initStack(value);

    pushStack(opt, (int)('#'));        //做一个开始的标记  与第一个进来的相互比较
    ELEM_TYPE result = 0;    //结果   //以为value 内部也是  char 类型
    char buf[128];
    int len = 0;
    char* start = nullptr;
    char* end = nullptr;
    char intbuf[16];

    cout << "***********************************************" << endl; //
    while ((char)(*getTop(opt)) != '#' || str[len] != '=') {

        if (isspace(str[len])) {
            if (DeBug)printf_s("第 %d 个为空!\n", len + 1);
            len++;
            continue;
        }
        ELEM_TYPE ret = (ELEM_TYPE)str[len];    //保存当前读取的  字符
        ELEM_TYPE outvalue_1, outvalue_2;    //用来保存出栈的值
        ELEM_TYPE outopt;
        
        if (!isOpt(ret, optstr, sizeof(optstr) / sizeof(optstr[0]))) {    //不是运算符的话就是  数值

            {// 这个模块是把  连续的 数字字符 转换成 int
                start = (char*)str + len;
                end = start + 1;
                while (!isOpt(int(*end), optstr, sizeof(optstr) / sizeof(optstr[0]))) {
                    end++;
                }
                snprintf(intbuf, sizeof(intbuf), start, end - start);
                ret = atoi(intbuf);
            }
            
            if (DeBug)printf_s("第 %d 个为数字: %d!\n", len + 1, ret);                                                        //入栈之后就继续扫描
            pushStack(value, ret);
            len += end-start;
            continue;
        }else {
            if (DeBug)printf_s("第 %d 个为运算符,正在进行操作 %c !\n", len + 1, (char)ret);

            switch (priority((char)(*getTop(opt)), (char)ret))
            {
            case '<':
                pushStack(opt, ret);
                if (DeBug)printf_s("第 %d 个为运算符,入栈 %c !\n", len + 1, ret);
                len++;
                break;
            case '>':
                popStack(opt, outopt);
                popStack(value, outvalue_1);
                popStack(value, outvalue_2);
                oper(outvalue_2, (char)outopt, outvalue_1, result);  //开始运算
                pushStack(value, result);
                if (DeBug)printf_s("**********结果 %d 入栈   %c 出栈!\n", result, outopt);
                break;
            case '=':
                popStack(opt, outopt);
                if (DeBug)printf_s(" ‘=’的情况下 %c 出栈!\n", outopt);
                len++;
                break;
            }
        }
    }

    const char* laopo = "珂珂宝贝1314";
    cout << "开始输出结果!" << endl;
    sprintf_s(buf, "%s %d ", str, *getTop(value));
    cout << buf << endl;

    Sleep(4000);
    cout << "等等, 答案好像不对 !" << endl;
    Sleep(4000);
    sprintf_s(buf, "%s %d%s ", str, *getTop(value), laopo);

    cout << "应该是  :";
    cout << buf << endl;
    

    destroyStack(opt);
    destroyStack(value);
    
    system("pause");
    _CrtDumpMemoryLeaks();
    return 0;
}

/***************函数定义区*********************/
bool initStack(stack& st) {
    st.base = new ELEM_TYPE[MAX_SIZE];
    if (!st.base) {
        return false;
    }
    st.top = st.base;
    return true;
}

bool pushStack(stack& st, ELEM_TYPE e) {
    if ((st.top - st.base) == MAX_SIZE) {//栈已经满了
        return false;
    }
    *(st.top++) = e;
    return true;
}

bool popStack(stack& st, ELEM_TYPE& e) {
    if (st.base == st.top) {//栈为空
        return false;
    }
    e = *(--st.top);
    return true;
}

void destroyStack(stack& st) {

    st.top = nullptr;

    if (st.base) delete[] st.base;

    return;
}

inline bool isEmpty(stack& st) {
    if (st.base == st.top) {
        return true;
    }
    else {
        return false;
    }
}

inline bool isFull(stack& st) {

    if (st.top - st.base == MAX_SIZE) {
        return true;
    }
    else {
        return false;
    }
}

void printStack(stack& st) {
    auto tmp = st.base;
    int i = 1;
    while (tmp != st.top) {
        printf_s(" %c       \n", *tmp);
        tmp++;
    }
    return;
}

inline int stackLen(stack& st) {
    auto len = st.top - st.base;
    return len;
}

inline ELEM_TYPE* getTop(stack& st) {
    if (!isEmpty(st)) {
        return st.top - 1;
    }
    else
        return nullptr;
}

bool isOpt(int a, char* optstr, int lenth) {

    for (int i = 0; i < lenth; i++) {
        if ((char)a == optstr[i])
            return true;
    }
    return false;
}

char priority(char lopt, char ropt) {
    switch (lopt) 
    {
    case '+':
        switch (ropt)
        {
        case '=':
        case '+':
        case '-':
        case ')':
        case '#':
            return '>';
        default:
            return '<';
        }
        
    case '-':
        switch (ropt) 
        {
        case '=':
        case '+':
        case '-':
        case ')':
        case '#':
            return '>';
        default:
            return '<';
        }
        
    case '*':
        switch (ropt) 
        {
        case '(':
            return '<';
        default:
            return '>';
        }
        
    case '/':
        switch (ropt) 
        {
        case '(':
            return '<';
        default:
            return '>';
        }
        
    case '(':
        switch (ropt) 
        {
        case ')':
            return '=';
        default:
            return '<';
        }

    case '#':
        switch (ropt)
        {
        case '#':
        case '=':
            return '=';
        default:
            return '<';
        }
    }
    return '\0';
}

void oper(ELEM_TYPE outvalue_1, char outopt, ELEM_TYPE outvalue_2, ELEM_TYPE& result) {

    int result_1 = 0;

    int value_1 = outvalue_1;
    int value_2 = outvalue_2;
    
    switch (outopt) {
    case '+':
        result_1 = value_1 + value_2;
        break;
    case '-':
        result_1 = value_1 - value_2;
        break;
    case '*':
        result_1 = value_1 * value_2;
        break;
    case '/':
        result_1 = value_1 / value_2;
        break;
    default:
        break;
    }
    result = result_1 ;
    return;
    
}

猜你喜欢

转载自blog.csdn.net/qq_44065088/article/details/102585382
今日推荐