/* 顺序栈表示:函数定义 */
/* 顺序栈表示:类型和界面函数声明 */
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。不同单词的首字母用大写。之后再具体看命名规则。
总结一下,写完这个算法也算是挺有成就感的事情了(虽然不是自己想出来的),对栈的基本操作和应用有了一丢丢的了解,印象也能更深。之后在学习数据结构的过程中还是会用实现例子的方法来加深了解和印象。