栈Stack

栈的定义

栈是一种先入后出的数据结构,如图所示结构

在C++中给出了相应的数据结构

stack<栈内元素类型> st;

栈的基本操作

入栈Push

操作如图所示,从栈顶插入一个元素

C++中对应的操作

st.push(元素)

取出栈顶元素Top

取出栈顶元素的值

C++中对应操作

栈顶元素的值 = st.top()

出栈Pop

 从栈顶弹出一个元素

C++中对应操作

st.pop()

 


数组模拟实现栈

stk[] 存储元素的数组

tt为 栈顶 

acwing828. 模拟栈

 输入样例:

10
push 5
query
push 6
pop
query
pop
empty
push 4
query
empty

 All in:

#include <iostream>

using namespace std;

const int N = 100010;
int tt;
int stk[N];

int main()
{
    int m;
    scanf("%d",&m);
    while (m --)
    {
        string op;
        cin >> op;
        if (op == "push") 
        {
            int x;
            scanf("%d", &x);
            stk[++ tt] = x;//向栈顶插入元素
        }
        if (op == "pop") tt --;
        if (op == "query") printf("%d\n",stk[tt]);
        if (op == "empty") //empty判断栈里是否为空
        {
            if (tt > 0) printf ("NO\n");
            else printf("YES\n");
        }
    }
}


表达式求值(C++)

acwing3302. 表达式求值

All in: 

#include <iostream>
#include <algorithm>
#include <stack>
#include <unordered_map>
#include <cstring>

using namespace std;
const int N = 100010;
unordered_map<char, int> pr{{'-', 1}, {'+', 1}, {'*', 2}, {'/', 2}};
char str[N];
stack<int> num;//存储数字
stack<char> op;//存储操作符

void eval()
{
    int num2 = num.top();
    num.pop();
    int num1 = num.top();
    num.pop();
    
    int x = 0;
    if (op.top() == '-')
    {
        x = num1 - num2;
    }
    else if (op.top() == '+')
    {
        x = num1 + num2;
    }
    else if (op.top() == '*')
    {
        x = num1 * num2;
    }
    else if (op.top() == '/')
    {
        x = num1 / num2;
    }
    op.pop();
    num.push(x);
}
int main()
{
    scanf("%s", str);
    
    int len = strlen(str);
    
    for (int i = 0; i < len; i ++ )
    {
        //如果是数字
        if (str[i] >= '0' && str[i] <= '9')
        {
            int x = 0, j = i;
            while (j < len && str[j] >= '0' && str[j] <= '9')
            {
                x = x * 10 + str[j] - '0';
                j ++;
            }
            i = j - 1;
            num.push(x);
        }
        else if (str[i] == '(')
        {
            op.push(str[i]);
        }
        else if (str[i] == ')')
        {
            while (op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while (op.size() && op.top() != '(' && pr[op.top()] >= pr[str[i]]) eval();
            op.push(str[i]);
        }
    }
    while(op.size()) eval();
    printf("%d\n", num.top());
}

 

中缀转后缀(C++)

 后缀表达式又称逆波兰表达式

中缀转后缀思路

1.遇到数字,加入后缀表达式中

2.遇到左括号,加入存运算符的栈中

3.遇到右括号,弹出存运算符的栈中元素直到遇到左括号,最后要将左括号弹出

4.遇到加减乘除,栈不为空,栈顶不为左括号,栈顶元素的优先级大于等于即将插入的运算符,弹出栈内元素

中缀转后缀C++实现

#include <iostream>
#include <stack>
#include <unordered_map>
#include <cstring>

using namespace std;

const int N = 100010;
unordered_map<char, int> pr{{'-', 1}, {'+', 1}, {'*', 2}, {'/', 2}};
stack<char> op;//存运算符
string res;//存后缀
char str[N];//读入中缀

int main()
{
	scanf("%s", str);
	
	int len = strlen(str);
	
	for (int i = 0; i < len; i ++ )
	{
		char c = str[i];
		
		//如果是数字 直接加到后缀表达式中
		if (c >= '0' && c <= '9')
		{
			res += c;
		}
		//左括号 入栈
		else if (c == '(') op.push(c);
		//右括号 弹出栈内元素直到遇到第一个右括号
		else if (c == ')')
		{
			while (op.top() != '(')
			{
				res += op.top();
				op.pop();
			}
			op.pop();
		}
		//加减乘除
		else
		{
			//当栈不为空 栈顶不为右括号 栈顶优先级大于等于即将插入元素的优先级 
			//弹出栈内元素 加入后缀表达式中
			while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c])
			{
				res += op.top();
				op.pop();
			}
			op.push(c);
		}
	}
	//当栈不为空 就将剩余的操作符加入后缀表达式
	while (op.size())
	{
		res += op.top();
		op.pop();
	}
	cout << res << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这个问题非常适合用程序解决。以下是用stack实现简单计算器的c代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #define STACKLEN 1000 /* 的最大容量 */ typedef struct { int top; /* 顶指针 */ double data[STACKLEN]; /* 元素数组 */ } Stack; void push(Stack *pstack, double value) { if (pstack->top == STACKLEN - 1) { printf("Error: stack overflow!\n"); exit(EXIT_FAILURE); } else { pstack->data[++pstack->top] = value; } } double pop(Stack *pstack) { if (pstack->top == -1) { printf("Error: stack underflow!\n"); exit(EXIT_FAILURE); } else { return pstack->data[pstack->top--]; } } bool is_digit(char c) { return (c >= '0' && c <= '9'); } int precedence(char op) { if (op == '+' || op == '-') return 1; else if (op == '*' || op == '/') return 2; else return 0; } double calculate(double left, char op, double right) { switch (op) { case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': return left / right; default: printf("Error: invalid operator!\n"); exit(EXIT_FAILURE); } } double eval(char *expr) { Stack operandStack; operandStack.top = -1; Stack operatorStack; operatorStack.top = -1; int len = strlen(expr); int i = 0; while (i < len) { char c = expr[i]; if (is_digit(c)) { double value = 0.0; while (i < len && is_digit(expr[i])) { value = value * 10.0 + (double)(expr[i] - '0'); i++; } push(&operandStack, value); } else { while (operatorStack.top != -1 && precedence(operatorStack.data[operatorStack.top]) >= precedence(c)) { char op = operatorStack.data[operatorStack.top--]; double right = pop(&operandStack); double left = pop(&operandStack); push(&operandStack, calculate(left, op, right)); } push(&operatorStack, c); i++; } } while (operatorStack.top != -1) { char op = operatorStack.data[operatorStack.top--]; double right = pop(&operandStack); double left = pop(&operandStack); push(&operandStack, calculate(left, op, right)); } return pop(&operandStack); } int main() { char s[1000]; printf("Please enter an expression: "); scanf("%s", s); double result = eval(s); printf("Result: %f\n", result); return 0; } ``` 这段代码定义了两个:一个操作数(operandStack)和一个操作符(operatorStack),通过不断入和出的操作,实现对表达式进行求值。其中,is_digit函数用于判断一个字符是否是数字;precedence函数用于比较两个运算符的优先级;calculate函数用于计算两个操作数和一个操作符的运算结果;eval函数是主函数,用于将输入的表达式转化为数字计算结果。 希望这个回答能够帮助您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值