• C++数据结构X篇_11_C++栈的应用-后缀表达式求解


    上篇C++栈的应用-中缀转后缀中我们介绍了我们所熟知的中缀表达式转为后缀表达式,那么如何通过后缀表达式获得原表达式的值呢?本篇将会参考博文C++栈的应用-后缀表达式求解介绍计算机是如何基于后缀表达式计算的?

    1. 后缀表达式求解计算规则

    1.1 计算规则

    遍历后缀表达式中的数字和符号

    • 对于数字:进栈
    • 对于符号
      • 从栈中弹出右操作数(例如:“10+5”中5即为右操作数)
      • 从栈中弹出左操作数(例如:“10+5”中10即为右操作数)
      • 根据符号进行计算
      • 将计算结果压入栈中
    • 遍历结束:栈中的唯一数字为计算结果

    1.2 对 8 3 1 - 5 * +的转换过程进行实例分析

    以下是遍历的过程:

    (1)遍历到1位置
    按照上面的规则,数字直接入栈,如下图所示:
    在这里插入图片描述
    (2)遍历到-运算符位置
    从栈中弹出右操作数1,然后从栈中弹出左操作数3,根据符号进行计算3-1=2,后将计算结果2压入栈中。
    在这里插入图片描述
    (3)遍历到*运算符位置
    从栈中弹出右操作数2,然后从栈中弹出左操作数5,根据符号进行计算2-5=10,后将计算结果10压入栈中。
    在这里插入图片描述
    (4)遍历到+运算符位置
    从栈中弹出右操作数10,然后从栈中弹出左操作数8,根据符号进行计算8-10=18,后将计算结果18压入栈中。
    在这里插入图片描述
    (5)遍历结束
    栈中的唯一数字18为计算结果,根据8 + (3 - 1) * 5即可算出计算结果就是18

    2. 后缀表达式求解代码实现

    2.1 栈的基本操作函数

    // 有关栈的基本操作
    //节点
    class linknode
    {
    public:
    	linknode* next;
    };
    //自定义数据
    class my_data
    {
    public:
    	linknode* node;
    	double num;
    };
    //链式栈
    class linkstack
    {
    public:
    	linknode head;
    	int size;
    };
    //初始化栈
    linkstack* init_linkstack()
    {
    	linkstack* stack = new linkstack;
    	stack->head.next = NULL;
    	stack->size = 0;
    	return stack;
    }
    //入栈
    void push_linkstack(linkstack* stack, linknode* data)
    {
    	data->next = stack->head.next;
    	stack->head.next = data;
    	stack->size++;
    }
    //出栈
    void pop_linkstack(linkstack* stack)
    {
    	stack->head.next = stack->head.next->next;
    	stack->size--;
    }
    //返回栈顶元素
    linknode* top_linkstack(linkstack* stack)
    {
    	return stack->head.next;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    2.2 判断函数与四则运算函数

    // 判断函数
    //判断字符是否为数字
    int isnumber(char c)
    {
    	return c >= '0' && c <= '9';
    }
    //判断是否为运算赋
    int isoperator(char c)
    {
    	return c == '+' || c == '-' || c == '*' || c == '/';
    }
    //四则计算
    double calculate(char c, double num1, double num2)
    {
    	if (c == '+')
    	{
    		return num1 + num2;
    	}
    	else if (c == '-')
    	{
    		return num1 - num2;
    	}
    	else if (c == '*')
    	{
    		return num1 * num2;
    	}
    	else if (c == '/')
    	{
    		return num1 / num2;
    	}
    	else
    	{
    		cout << "非四则运算符:" << c << endl;
    		return NULL;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    2.3 主函数代码

    int main()
    {
    	linkstack* stack = init_linkstack();
    	char str[] = "8 3 1 - 5 * +";
    	for (int i = 0; i < sizeof(str) / sizeof(char); i++) //逐字符遍历str获得操作符;
    	{
    		my_data* data = new my_data;
    		data->node = NULL;
    		data->num = str[i] - '0';
    		//是数字直接进栈
    		if (isnumber(str[i]))
    		{
    			push_linkstack(stack, (linknode*)data);
    		}
    		//是运算符从栈中取出两数值进行计算
    		if (isoperator(str[i]))
    		{
    			//从栈中取出两个数据
    			double num1 = ((my_data*)top_linkstack(stack))->num; //右计算值
    			pop_linkstack(stack);
    			double num2 = ((my_data*)top_linkstack(stack))->num; //左计算值
    			pop_linkstack(stack);
    			//两数字num1、num2的计算结果ans
    			double ans = calculate(str[i], num2, num1);
    			//计算结果 ans入栈
    			my_data* res = new my_data;
    			res->num = ans;
    			push_linkstack(stack, (linknode*)res);
    		}
    	}
    	//在栈中取出最终结果
    	if (stack->size == 1)
    	{
    		my_data* res = new my_data;
    		res = (my_data*)top_linkstack(stack);
    		pop_linkstack(stack);
    		cout << "计算结果为:" << res->num << endl;
    	}
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.4 运算结果

    在这里插入图片描述

    2.5 整体代码

    #include
    using namespace std;
    
    // 有关栈的基本操作
    //节点
    class linknode
    {
    public:
    	linknode* next;
    };
    //自定义数据
    class my_data
    {
    public:
    	linknode* node;
    	double num;
    };
    //链式栈
    class linkstack
    {
    public:
    	linknode head;
    	int size;
    };
    //初始化栈
    linkstack* init_linkstack()
    {
    	linkstack* stack = new linkstack;
    	stack->head.next = NULL;
    	stack->size = 0;
    	return stack;
    }
    //入栈
    void push_linkstack(linkstack* stack, linknode* data)
    {
    	data->next = stack->head.next;
    	stack->head.next = data;
    	stack->size++;
    }
    //出栈
    void pop_linkstack(linkstack* stack)
    {
    	stack->head.next = stack->head.next->next;
    	stack->size--;
    }
    //返回栈顶元素
    linknode* top_linkstack(linkstack* stack)
    {
    	return stack->head.next;
    }
    
    // 判断函数
    //判断字符是否为数字
    int isnumber(char c)
    {
    	return c >= '0' && c <= '9';
    }
    //判断是否为运算赋
    int isoperator(char c)
    {
    	return c == '+' || c == '-' || c == '*' || c == '/';
    }
    //四则计算
    double calculate(char c, double num1, double num2)
    {
    	if (c == '+')
    	{
    		return num1 + num2;
    	}
    	else if (c == '-')
    	{
    		return num1 - num2;
    	}
    	else if (c == '*')
    	{
    		return num1 * num2;
    	}
    	else if (c == '/')
    	{
    		return num1 / num2;
    	}
    	else
    	{
    		cout << "非四则运算符:" << c << endl;
    		return NULL;
    	}
    }
    
    int main()
    {
    	linkstack* stack = init_linkstack();
    	char str[] = "8 3 1 - 5 * +";
    	for (int i = 0; i < sizeof(str) / sizeof(char); i++) //逐字符遍历str获得操作符;
    	{
    		my_data* data = new my_data;
    		data->node = NULL;
    		data->num = str[i] - '0';
    		//是数字直接进栈
    		if (isnumber(str[i]))
    		{
    			push_linkstack(stack, (linknode*)data);
    		}
    		//是运算符从栈中取出两数值进行计算
    		if (isoperator(str[i]))
    		{
    			//从栈中取出两个数据
    			double num1 = ((my_data*)top_linkstack(stack))->num; //右计算值
    			pop_linkstack(stack);
    			double num2 = ((my_data*)top_linkstack(stack))->num; //左计算值
    			pop_linkstack(stack);
    			//两数字num1、num2的计算结果ans
    			double ans = calculate(str[i], num2, num1);
    			//计算结果 ans入栈
    			my_data* res = new my_data;
    			res->num = ans;
    			push_linkstack(stack, (linknode*)res);
    		}
    	}
    	//在栈中取出最终结果
    	if (stack->size == 1)
    	{
    		my_data* res = new my_data;
    		res = (my_data*)top_linkstack(stack);
    		pop_linkstack(stack);
    		cout << "计算结果为:" << res->num << endl;
    	}
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
  • 相关阅读:
    CPU与GPU到底有什么区别?
    【C语言练习——交换两个变量的值】
    MySQL数据库介绍和部分基本操作
    【数据结构】红黑树
    CNN详解——反向传播过程
    spark底层原理理解--高级进阶
    若依使用EasyExcel导入和导出数据
    system函数实践1:system函数进程的爸爸是谁?
    vue原理相关
    【每日一题Day334】LC2591将钱分给最多的儿童 | 贪心
  • 原文地址:https://blog.csdn.net/Dasis/article/details/132789113