算法学习——栈的应用之逆波兰(后缀)表达式转换

已知一组中缀表达式,求其后主表达式

例:

     中缀表达式:(1+2)*3+(4+6)*(5*6)+7

     后缀表达式:1 2+3*4 6+5 6** +7+

求解此问题通常有两种方法:

1. 利用栈来存储运算符,通过比较优先级进行出入栈操作。

2. 将中缀表达式转换为二叉树,对二叉树进行后序遍历。

本文着重分析并实现方法1. 对于栈解法,应遵循以下原则:

1.  数字直接输出,不入栈。

2.  除右括号外,所有运算符入栈。

3.  入栈前与栈顶元素对比,如果栈顶运算符优先级高,则不断弹出,直至新栈顶为相对低优先级运算符。

4.  遇到右括号时,不断弹出栈顶直至最顶左括号弹出。输出除左括号外所有运算符。(左括号也弹出,但不输出)

5.  输入结束时,应弹出并输出所有运算符。(左括号只弹,不输出)


#pragma once
#ifndef _STACK_H
#define MAX 1000
typedef int ElementType;
struct MyStack {
	ElementType *arr;
	int count;
	int top;
};
typedef struct MyStack *stack;

void push(ElementType e, stack s);
void pop(stack s);
int isEmpty(stack s);
int isFull(stack s);
void makeEmpty(stack s);
stack creatStack(int maxEle);
void distroyStack(stack s);
ElementType top(stack s);

#endif
// stack.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stack.h"
#include <conio.h>

int arr[100];
MyStack ss;
stack gs;

void push(ElementType e, stack s)
{
	if (!isFull(s)) {
		s->arr[++(s->top)] = e;
	}
}

void pop(stack s)
{
	if (!isEmpty(s))
		s->top--;
}

int isEmpty(stack s)
{
	if(!s->top)
		return 1;
	return 0;
}

int isFull(stack s)
{
	if (s->top == s->count)
		return 1;
	return 0;
}

void makeEmpty(stack s)
{
	int i = 0;
	for (i = 0; i < s->count; i++) {
		s->arr[i] = 0;
	}
	s->top = 0;
}

stack creatStack(int maxEle)
{
	ss.arr = arr;
	ss.top = 0;
	ss.count = maxEle;

	makeEmpty(&ss);

	return &ss;
}

void distroyStack(stack s)
{
}

ElementType top(stack s)
{
	if (!isEmpty(s)) {
		return s->arr[s->top];
	}
	return 0;
}


int main() {
	char c,c1;
	MyStack ss;
	ss.arr = arr;
	ss.top = 0;
	ss.count = 20;

	while ((c = getchar()) != 'q') {
		if (c >= '0' && c <= '9')
			printf("%c",c);
		if (c == '+' || c == '-') {
			c1 = top(&ss);
			while (!isEmpty(&ss) && c1 != '(') {
				printf("%c", c1);
				pop(&ss);
				c1 = top(&ss);
			}
			push(c, &ss);
		}
		if (c == '*' || c == '/') {
			c1 = top(&ss);
			while (!isEmpty(&ss) && (c1 == '*' || c1 == '/')) {
				printf("%c", c1);
				pop(&ss);
				c1 = top(&ss);
			}
			push(c, &ss);
		}
		if (c == '(') {
			push(c, &ss);
		}
		if (c == ')') {
			c1 = top(&ss);
			int brk = 0;
			while (!isEmpty(&ss) && brk == 0) {
				if (c1 != '(')
					printf("%c", c1);
				else
					brk = 1;
				pop(&ss);
				c1 = top(&ss);
			}
		}
		if (c == 10) {
			while (!isEmpty(&ss)) {
				c1 = top(&ss);
				pop(&ss);
				if (c1 != '(' && c1 != ')') {
					printf("%c", c1);
				}
			}
		}
	}



	return 0;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值