简易计算器HDU1237(栈的应用)

/* 顺序栈表示:函数定义 */


/* 顺序栈表示:类型和界面函数声明 */

enum { MAXNUM = 20    /* 栈中最大元素个数,应根据需要定义 */
};
     
typedef double DataType; /* 栈中元素类型,应根据需要定义 */

struct SeqStack {	  /* 顺序栈类型定义 */
    int  t; 		  /* 栈顶位置指示 */
    DataType  s[MAXNUM];
};

typedef  struct SeqStack  *PSeqStack;	/* 顺序栈类型的指针类型 */ 


/*创建一个空栈;为栈结构申请空间,并将栈顶变量赋值为-1*/
PSeqStack  createEmptyStack_seq( void ) {  
    PSeqStack pastack = (PSeqStack)malloc(sizeof(struct SeqStack));
    if (pastack==NULL)
        printf("Out of space!! \n");
    else
        pastack->t = -1;
    return pastack;
}

/*判断pastack所指的栈是否为空栈,当pastack所指的栈为空栈时,则返回1,否则返回0*/
int  isEmptyStack_seq( PSeqStack pastack ) {
    return pastack->t == -1;
}

/* 在栈中压入一元素x */
void  push_seq( PSeqStack pastack, DataType x ) {  
    if( pastack->t >= MAXNUM - 1  )
        printf( "Stack Overflow! \n" );
    else {  
        pastack->t++;
        pastack->s[pastack->t] = x;
    }
}

/* 栈顶元素出栈,x存储数据 */
void  pop_seq( PSeqStack pastack, DataType *x ) {  	
    if (pastack->t == -1 )
        printf( "Underflow!\n" );
    else
	{
		*x=pastack->s[pastack->t];
        pastack->t--;
	}
}

/*只出栈,不返回元素*/
void  dele_seq( PSeqStack pastack ) {  	
    if (pastack->t == -1 )
        printf( "Underflow!\n" );
    else
        pastack->t--;
}

/* 当pastack所指的栈不为空栈时,求栈顶元素的值 */
DataType top_seq( PSeqStack pastack ) {
    return pastack->s[pastack->t];
}
#include"stack.h"


double getSum(PSeqStack pastack , int* posture, int posLength)
{
	double x1;
	double x2;
	double temp=0;
	int i=0;
	int j=0;
	double top;

		do{
			do //把数字入栈
			{
				push_seq(  pastack, posture[i] );
				top=top_seq( pastack );
				i++; //i=6
			}while(top!='-' && top!='+' && top!='*' && top!='/');

			dele_seq(  pastack );  //把'-'(非数字符号)
			pop_seq(  pastack,  &x1 );  //把栈顶数字赋给x1 3
			pop_seq(  pastack,  &x2 );  //把栈顶数字赋给x2 2
	
			//x1,x2的运算,结果赋给temp
			if(posture[i-1]=='-') temp=(x2-x1);  
		    if(posture[i-1]=='*') temp=(x2*x1);
			if(posture[i-1]=='+') temp=(x2+x1);
			if(posture[i-1]=='/') temp=(x2/x1);

			push_seq( pastack, temp);

		}while(i<posLength); 

		printf("式子的结果为:%.2f\n",temp);
		return 0;
}

void transPos(int* pos1, int posLength, int* pos2)
{
	double x;
	int ix;
	int i=0;
	int j=0;
	int top;

	PSeqStack stack;
	stack=createEmptyStack_seq();

	do{
		if(pos1[i]=='(') 
			push_seq( stack, pos1[i] );
		if(pos1[i]==')')
		{
			do{
				pop_seq(  stack,  &x );
				ix=(int)x;
				
				pos2[j]=ix;  
				j++;

				top=top_seq( stack );
			}while(top!='(');
		dele_seq(  stack );
		}

		if(pos1[i]!='-' && pos1[i]!='+' && pos1[i]!='*' && pos1[i]!='/' && pos1[i]!='(' && pos1[i]!=')')
		{

			pos2[j]=pos1[i];
			j++;
		}

		if(pos1[i]=='*' || pos1[i]=='/') 
		{
			top=top_seq( stack );
			if(top=='+' || top=='-')
				push_seq(  stack, pos1[i] );
		}

		if(pos1[i]=='+' || pos1[i]=='-') 
		{
			top=top_seq( stack );
			if(top=='*' || top=='/')
			{
				while(isEmptyStack_seq( stack )!=1)
				{
					pop_seq(  stack,  &x );
					ix=(int)x;

					pos2[j]=ix;
					j++;
				}
				push_seq(  stack, pos1[i] );
			}
			else
				push_seq(  stack, pos1[i] );
		}
				
		i++;

	}while(i<posLength);


	while(isEmptyStack_seq( stack )!=1)
		{
			pop_seq(  stack,  &x );
			ix=(int)x;
			pos2[j]=ix;  
			j++;
		}
}


void getNewPos(int nLen, int* newPos)
{
	for(int j=0; j<nLen; j++) 
		{
			if(newPos[j]=='+' || newPos[j]=='-' || newPos[j]=='*' || newPos[j]=='/')
				printf("%c ",newPos[j]);
			else
				printf("%d ",newPos[j]);
		}
}


int getNewLength(int* oldPos, int Len)
{
	int oLen;
	oLen=Len;
	for(int i=0; i<oLen; i++)
	{
		if(oldPos[i]=='(' || oldPos[i]==')') Len--;
	}
	return Len;
}
#include<stdio.h>
#include <stdlib.h>
#include"test2.h"

void main()
{
	int length;
	int arr1[]={3,'+',6,'*',5,'-','(',15,'+',2,')'};
	int* const arr2 = (int*)malloc(sizeof(int)*length);

	length = sizeof(arr1) / sizeof(int);
	

	PSeqStack stack;
	stack=createEmptyStack_seq();

	printf("原式= ");
	for(int i=0; i<length; i++)
	{
		if(arr1[i]=='+' || arr1[i]=='-' || arr1[i]=='*' || arr1[i]=='/' || arr1[i]=='(' || arr1[i]==')')
			printf("%c ",arr1[i]);
		else
			printf("%d ",arr1[i]);
	}

	transPos(arr1, length, arr2);
	printf("\n");

	printf("后缀表达式= ");
	getNewPos(getNewLength(arr1, length), arr2);
	
	printf("\n");
	getSum(stack , arr2, getNewLength(arr1, length));

}

题源:HDU1237
题目不是我自己从0开始想的,头文件<stack.h>系老师给的【栈的基本操作】,其他代码是自己写的。参考了《大话数据结构》的算法,看图示一行一行敲的代码…

大概收获:
1.碰到这种有规律循环的算法时,先自己列出一个例子,一步一步去实现,多写几次 if 语句,不怕敲重复的代码。运行例子之后成功了再找出循环的规律,在另一个cpp文件里做 while() 循环实现。成功之后搬回原来的头文件中,再另举一个例子检查是否成功。

2.一定要利用好debug!!!之前写过的代码太弱智了,自己可以直接看出 or 用笔在纸上写运行步骤+各种变量的数值变化。一旦循环复杂起来,运行的数据较多时,调试简直救我。

*3.这个算法不完整(就是题目是不通过的)。题目要求是从键盘输入原式,我这里只是把原式的整形数字和符号一个个敲入数组。现在解决不了的问题是:不能在整型数组里面输入字符‘+’、‘-’等,输入后运行不成功。

4.这次的函数和变量命名相比之前稍微有了一点逻辑,不是用拼音命名… 函数命名要活用set、get。不同单词的首字母用大写。之后再具体看命名规则。

总结一下,写完这个算法也算是挺有成就感的事情了(虽然不是自己想出来的),对栈的基本操作和应用有了一丢丢的了解,印象也能更深。之后在学习数据结构的过程中还是会用实现例子的方法来加深了解和印象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值