逆波兰式 栈实现

因为做二叉树非递归的前后中遍历,用到栈的方法。xpp说那就干脆把四则运算,逆波兰式 栈的实现做了。

这是参考别人的程序写的,注释比较乱。而且这个是直接实现计算机计算的四则运算,没有将逆波兰的表达式打印出来。今天腰太酸了,明天改一改,把逆波兰式打印出来噻333333.栈还有迷宫算法是不是???现在脑子里之前看的非递归遍历都想不起来了我擦

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include"string.h"


#define MAX_OPE_LEN 10
#define MAX_STRING_LEN 100
#define MAX_STACK_LEN 100

//
typedef struct operater
{
	char name;
	int pior;
	int opernum;
}Operater;


Operater opStack[MAX_OPE_LEN];
int opStacktop=-1;//外加一个指示栈顶的数,这也挺奇葩的

double   numStack[MAX_STACK_LEN];
int numStacktop=-1;

int getPior(char name)
{
	if (name=='('||name==')')//注意括号的优先级
	{	return 0;}
	if (name=='+'||name=='-')
	{	return 1;}
	if(name=='*'||name=='/')
	{	return 2;}
	if(name=='!')
	{	return 3;}
	exit(1);//其他情况则直接退出
}

int getopernum(char name)
{
	if(name=='+'||name=='-'||name=='*'||name=='/')
	{	return 2;}
	if(name=='!')
	{	return 1;}
	if(name=='('||name==')')//特别注意括号的操作数为0;
	{	return 0;}
	exit(1);
}

void pushoperater(Operater op)//入栈操作的是一个 运算符
{
	if (opStacktop<MAX_OPE_LEN-1 )
	{opStack[++opStacktop]=op;}
	else
	{exit(1);}
}

Operater popoperater()
{
	if(opStacktop!=-1)
	{return opStack[opStacktop--];}
	else
	{exit(1);}
}


void pushnum(double num)
{
	if (numStacktop<MAX_STACK_LEN-1)
	{numStack[++numStacktop]=num;}
	else
	{exit(1);}
}

double popnum()
{
	if (numStacktop!=-1)
	{return numStack[numStacktop--];}
	else
	{exit(1);}
}

//将输入的浮点数字符转化为double
//这个部分也是难点之一

double getNumfromString(char *s,int *i)//char *s是char类型的字符输入开始
{
	static char string[MAX_STRING_LEN];
	int j=0;
	while (*s>='0'&&*s<='9')
	{
		string[j++]=*s;
		s++;
	}
	if (*s=='.')
	{
		string[j++]=*s;
		s++;
		while(*s>='0'&&*s<='9')
		{
			string[j++]=*s;
		    s++;
		}

	}
	(*i)=(*i)+j;
	string[j]='\0';//表示字符结束
	return atof(string);//将这个字符转化为num
}

double operater2num(Operater op)
{
	double num2=popnum();
	double num1=popnum();
	if (op.name=='+')
	{return num1+num2;}
	if (op.name=='-')
	{return num1-num2;}
	if(op.name=='*')
	{return num1*num2;}
	if(op.name=='/')
	{return num1/num2;}
	{exit(1);}
}
//=============这部分也是比较难的,暂时可以不看啊===========
double operater1num(Operater op)//非操作?为何是这样??
{
    double num = popnum();
    if (op.name == '!')
    {
        double result = 1;
        while (num > 1)
        {
            result *= num;
            num--;
        }
        return result;
    }
    exit(1);
}

double operater(Operater op)
{
	if (op.opernum==2)
	{return operater2num(op);}
	if (op.opernum==1)
	{return operater1num(op);}
	exit(1);
}

//进入复杂的主函数操作
int main()
{
	char string[MAX_STRING_LEN ];
	printf("输入中缀运算表达式:\n");
	scanf("%s",string);//注意scanf的用法,输入到string中。%S表明输入的是字符串啊啊啊啊啊啊,%f,输入的是float型啊啊啊啊,并且没有该死的\n

	Operater op,opTop;//后者为栈顶运算符,这个用来表示操作符到了最底部
	opTop.name='#';
	opTop.opernum=0;
	opTop.pior=0;

    pushoperater(opTop);

	int i=0;
	for(i;string[i]!='\0'&&string[i]!='=';)
	{
		if (string[i]>='0'&&string[i]<='9')
		pushnum(getNumfromString(&string[i],&i));//把从i开始的数字都取完,转成num压入栈
    	else
     	{
	    	op.name=string[i];
	    	op.opernum=getopernum(op.name);
	    	op.pior=getPior(op.name);
	    	opTop=popoperater();//把操作符的栈顶操作符与 新发现的操作符对比

			if (op.name=='(')
				{
					pushoperater(opTop);
				    pushoperater(op);
			}
			else if (op.name==')')
			{
				while(opTop.name!='(')//只要没到左括号,将这之间的操作数 与numStack中的Num取出来实行运算,运算结果压入numStack

				{
					pushnum(operater(opTop));
					opTop=popoperater();
				}

			}
			else
			{
				if (opTop.name!='#'&&op.pior<=opTop.pior)
				{
					pushnum(operater(opTop));
					
				}
				else
				{
					pushoperater(opTop);
				}
				pushoperater(op);
			}
				
			i++;//因为操作符是一个一个的字符,上面字符与数字转换的时候,可能不是一个一个的加的
     	}   
		
   //string已经转换完了,这个时候操作符栈还有剩,则全部取出来操作
		
       }
       while((opTop = popoperater()).name != '#')
		{
			pushnum(operater(opTop));
			
		}
		 printf("%f\n", popnum());
	     system("pause");
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我理解了你的问题。逆波兰式代码是一种基于的算法,在其中运算符相对于操作数先被处理。以下是一个示例C语言逆波兰式代码: ``` #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STACK_SIZE 500 double stack[STACK_SIZE]; int top = 0; void push(double value) { if (top == STACK_SIZE) { printf("Error: Stack overflow\n"); exit(1); } else { stack[top++] = value; } } double pop() { if (top == 0) { printf("Error: Stack underflow\n"); exit(1); } else { return stack[--top]; } } double evaluate(char *expression) { char *p = expression; double a, b; while (*p) { if (isdigit(*p) || ((*p == '-') && isdigit(*(p+1)))) { push(strtod(p, &p)); } else { switch (*p) { case '+': b = pop(); a = pop(); push(a + b); break; case '-': b = pop(); a = pop(); push(a - b); break; case '*': b = pop(); a = pop(); push(a * b); break; case '/': b = pop(); a = pop(); if (b == 0) { printf("Error: Division by zero\n"); exit(1); } else { push(a / b); } break; default: printf("Error: Invalid expression\n"); exit(1); } p++; } } return pop(); } int main() { char expression[500]; double result; printf("Enter an expression in postfix notation (RPN):\n"); fgets(expression, 500, stdin); result = evaluate(expression); printf("Result = %f\n", result); return 0; } ``` 这个代码实现了一个计算逆波兰式的算法,并且支持四个基本运算:加、减、乘、除。程序先将表达式中的数字字符串转换成双精度浮点数,并将它们压入中。当遇到运算符时,从中弹出两个数进行运算,并将结果压入中。最后,当整个表达式都处理完时,中剩下的一个数就是表达式的计算结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值