逆波兰计数器 栈的实现

原创 2018年04月17日 18:20:30

又称后缀计数器

用栈把原式写为逆波兰式子,保存在数组里面并打印。

用栈根据逆波兰式子的形式计算出结果。

以下代码:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define INITSIZE 20	
#define INCREASE 5
typedef struct Stack {
	char*top;
	char*base;
	int stackSize;
}Stack;
void InitStack(Stack*s) {
	s->base = (char*)malloc(sizeof(char));//相当于为首地址申请空间
	s->top = s->base;
	s->stackSize = INITSIZE;
}
void Push(Stack*s, char c) {
	if (s->top- s->base>=s->stackSize) {
		s->base = (char*)realloc(s->base, (s->stackSize + INCREASE) * sizeof(char));
		//为s->base赋一个新的数值空间,并把s->base移过去
		s->top = s->base + s->stackSize;//把s->top
		s->stackSize = s->stackSize + INCREASE;
	}
	*(s->top++) = c;
}
void Pop(Stack*s, char*e) {
	if (s->top == s->base)
		return;
	*e = *(--s->top);
}
int getLen(Stack*s) {
	return s->top - s->base;
}
void ClearStack(Stack*s) {
	s->top = s->base;
}

//实现逆波兰计数器(后缀计数器)
char b[100] = { 0 };
typedef struct stack2 {
	double base[20];
	int top;
}Stack2;
int NiBoLan(Stack*s, char*a) {
	int i =0, j = 0;
	char e;
	while (a[i]) {
		if (a[i] >= '0'&&a[i] <= '9')
			b[j++] = a[i];
		else if (a[i] == ')') {
			Pop(s, &e);//s已经是个指针了,不能再引用了
			while (e != '(') {
				b[j++] = ' ';//把逆波兰实现的数据存到数组b上,数字和符号之间以空格相隔
				b[j++] = e;
				Pop(s, &e);
			}
		}
		else if (a[i] == '+' || a[i] == '-') {
			b[j++] = ' ';
			if (s->top == s->base || *(s->top - 1) == '(')
				Push(s, a[i]);
			else{//注意else if的区别
				while (getLen(s) && *(s->top - 1) != '(') {
					Pop(s, &e);
					b[j++] = e;
					b[j++] = ' ';
				}
				Push(s, a[i]);
			}
		}
		else if (a[i] == '*' || a[i] == '/' || a[i] == '(') {
			if(a[i]!='(')
				b[j++] = ' ';
			Push(s, a[i]);
		}
		else return 0;
		i++;
	}
	while (s->top!=s->base) {
		Pop(s, &e);
		b[j++] = ' ';
		b[j++] = e;
	}
	return 1;
}
double result(Stack2 s) {
	int sum = 0, i = 0,j;
	char num[10];
	double e, d;
	while (b[i]) {
		j = 0;
		if (b[i] >= '0'&&b[i] <= '9') {
			while (b[i] != ' '&&b[i] >= '0'&&b[i] <= '9') {
				num[j++] = b[i];
				num[j] = 0;//要在num中字符的后一位加上'\0',表示字符串的终止
				i++;
			}
			e = atof(num);
			s.base[++s.top] = e;//进行入栈
		}
		if (s.top > 0) {
			switch (b[i])
			{
			case '+':
				s.base[s.top - 1] = s.base[s.top] + s.base[s.top - 1];
				s.top--;
				break;
			case '-':
				s.base[s.top - 1] = s.base[s.top - 1] - s.base[s.top];
				s.top--;
				break;
			case '*':
				s.base[s.top - 1] = s.base[s.top] * s.base[s.top - 1];
				s.top--;
				break;
			case '/':
				s.base[s.top - 1] = s.base[s.top - 1] / s.base[s.top];
				if (s.base[s.top] == 0) {
					printf("出现浮点错误!\n");
					return -1;
				}
				s.top--;
				break;
			default:
				break;
			}
		}
		i++;
	}
	return s.base[s.top];
}

int main() {
	Stack s;
	InitStack(&s);
	Stack2 s2 = {
		{ 0 },-1
	};//对s2赋予初值
	char a[100] = { 0 };
	printf("请输入一个算式:");
	scanf("%s", a);
	int IsCorrect = NiBoLan(&s, a);
	if (IsCorrect) {
		for (int i = 0; b[i]; i++)
			printf("%c", b[i]);
		printf("\n");
	}
	else printf("输入的算式有误!\n");
	printf("最后结果为:%.2lf\n", result(s2));
	return 0;
}

【Python全栈】第五周 Python Web项目开发实现(上)

-
  • 1970年01月01日 08:00

C++学习之(栈) 实践之(逆波兰公式)

栈(statck)这种数据结构在计算机中是相当出名的。栈中的数据是先进后出的(First In Last Out, FILO)。栈只有一个出口,允许新增元素(只能在栈顶上增加)、移出元素(只能移出栈顶...
  • qingzijin2010
  • qingzijin2010
  • 2013-10-29 09:12:25
  • 2871

数据结构---栈--逆波兰算法

逆波兰:不需要括号的后缀表示法 例:9+( 3 - 1 )+10  ÷ 2 后缀表示法:“ 9 3 1 - 3 * + 10 2  /+” 程序表示的思路规则:        从左向右遍历表达...
  • qq_33531400
  • qq_33531400
  • 2016-12-01 22:16:23
  • 309

表达式计算器(逆波兰法)栈操作(C语言实现)

可能很多的同学在学数据结构的时候。说到栈,都会有一道很经典的题目,那就是用栈来实现计算器。我们都知道普通的计算写起来是很简单的,但是如果涉及到左右括号以及加减乘除组成的运算式的时候则写起程序时便不那么...
  • zxnsirius
  • zxnsirius
  • 2016-04-07 19:03:41
  • 2983

逆波兰计算器加强版:多项式

不说了不说了,,, 链表感觉白学了(学了吗?)= = 鲍鱼鲍鱼//cww 多项式计算器 #include #include #include using namespace std;struc...
  • cww97
  • cww97
  • 2016-03-22 00:10:22
  • 810

数据结构与算法之栈的应用“逆波兰表达式法”

1 基本信息1.1 表达式逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:正常的表达式...
  • chenliguan
  • chenliguan
  • 2016-10-15 16:34:12
  • 683

利用栈实现逆波兰计算

#include #include #include #define STACK_INIT_SIZE 20 #define STACKINCREMENT 10 #define MAXBUFFER 1...
  • xiao_lxl
  • xiao_lxl
  • 2014-09-27 15:16:42
  • 839

栈_逆波兰表达式_计算器实现_Golang版本

逆波兰表达式可以讲复杂的计算过程转化为简单的操作过程,进而得出答案。 比如 (a+b)*(b-c) 按照逆波兰表达式的规则得到 :ab+bc-*   将该表达式的字符以及符号,按照从左到右的顺序,依次...
  • u012807459
  • u012807459
  • 2015-02-01 09:25:08
  • 998

逆波兰式递归实现

  • 2013年12月05日 13:34
  • 1KB
  • 下载

栈的应用 - 波兰式与逆波兰式

上一篇笔记中,简单讲到了栈的特性,并且给出了栈的实现,现在要利用栈来实现表达式的求值问题。   有三个名词与表达式的计算密切相关,分别是中缀表达式、前缀表达式和后缀表达式,它们都是表达式的一种记法,区...
  • u011836061
  • u011836061
  • 2015-08-05 15:14:07
  • 1853
收藏助手
不良信息举报
您举报文章:逆波兰计数器 栈的实现
举报原因:
原因补充:

(最多只允许输入30个字)