数据结构之栈(后缀表达式转中缀表达式)

          • 1、栈表的初始化
          • 2、后缀表达式
          • 3、中缀表达式 转 后缀表达式
          • 4、主程序实现逻辑
          • 5、遇到的问题

**正文实现的功能:**把像(1+2*3)*2-4#的表达式算出来
参照逻辑:小甲鱼的数据结构、大话数据结构
整合了一些功能

1、栈表的初始化
#include 
#include 
#include 
#include 

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10
#define MAXBUFFER       10
using namespace std;


typedef double ElemType;
//栈的结构体
typedef struct
{
	ElemType *base;
	ElemType *top;
	int stackSize;
}sqStack;    

//初始化栈
void InitStack(sqStack *s)
{
	s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
	if (!s->base)
		exit(0);

	s->top = s->base;
	s->stackSize = STACK_INIT_SIZE;
}

//压栈
void Push(sqStack *s, ElemType e)
{
	// 栈满,追加空间,鱼油必须懂!
	if (s->top - s->base >= s->stackSize)
	{
		s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
		if (!s->base)
			exit(0);

		//s->top = s->base + s->stackSize; 
		//第一时间并没有添加如此多的元素,所以没必要
		s->stackSize = s->stackSize + STACKINCREMENT;
	}

	*(s->top) = e;      // 存放数据
	s->top++;
}
//出栈
void Pop(sqStack *s, ElemType *e)
{
	if (s->top == s->base)
		return;

	//*e = *--(s->top);   // 将栈顶元素弹出并修改栈顶指针
	*e =* (s->top-1);
	s->top--;
}
//栈元素的长度
int StackLen(sqStack s)
{
	return (s.top - s.base);
}
//遍历栈
void StackTraverse(sqStack s)
{
	while (s.base != s.top)
	{
		s.top--;
		printf("%.1f\n", *s.top);
	}
}
2、后缀表达式
/*
  返回值:计算之后的值
  参数1:后缀表达式的字符串
  参数2:栈表,可以用局部变量
*/
double GetValue(char* cSrc,sqStack s)  
{
	int j = 0; char a[10];int i=0;
	ElemType c, d;

	printf("请输入你的表达式\n");
	while (cSrc[j] != '#')   //判断结束符
	{
		while (int(cSrc[j]) <= 57 && int(cSrc[j]) >= 48)
		{
			a[i] = cSrc[j];
			a[i + 1] = '\0';  //c++中字符串以字符‘\0’结尾,所以每个字符串都有额外一个字符的开销。
			i++;
			if (i > 10)
				printf("输入长度超限");
			j++;
			if (cSrc[j] == ' ') //判断下一个是否是 空格(分离出数字)
			{
				Push(&s, atof(a));
				printf("传入的数据\n");
				StackTraverse(s);
				i = 0;
				break;
			}
		}
		switch (cSrc[j])
		{
		case('+'):
			Pop(&s, &c);
			Pop(&s, &d);
			Push(&s, c + d);
			break;
		case('-'):
			Pop(&s, &c);
			Pop(&s, &d);
			Push(&s, d - c);
			break;
		case('*'):
			Pop(&s, &c);
			Pop(&s, &d);
			Push(&s, d * c);
			break;
		case('/'):
			Pop(&s, &c);
			Pop(&s, &d);
			if (c == 0)
			{
				printf("除数已经为0");
				break;
			}
			Push(&s, d / c);
			break;
		default:
			break;
		}
		j++;
	}
	Pop(&s, &c);
	return c;
}
3、中缀表达式 转 后缀表达式
//返回值 可以用全局变量,也可以传一个字符指针作为参数
char* GetInfix(char* ch)
{
	char s[100]; int i = 0;int j=0;
	sqStack p; ElemType e;


	InitStack(&p); //初始化栈
	while (ch[i] != '#')
	{
		while (ch[i] >= '0' && ch[i] <= '9')
		{
			s[j] = ch[i];
			j++;
			i++;
			if (ch[i]<'0' || ch[i]>'9')
			{
				s[j] = ' ';
				j++;
			}
		}
//并列条件,先判断谁都行
		if (')'==ch[i])
		{ 
			printf("存了多少个\n");
			StackTraverse(p);
  			Pop(&p,&e);
			while ('(' != char(e))
			{
				s[j] = char(e);
				j++;
				Pop(&p,&e);
			}
		}
		else if ('+' == ch[i] || '-' == ch[i])  //权限最低,权限高的弹出
		{
			if (!StackLen(p)) //如果为空压栈
			{
				Push(&p, ch[i]);
			}
			else {
				do {
					Pop(&p, &e);          //弹出元素
					if ('(' == char(e))
					{
						Push(&p, e);//再次压入栈,为了上面的判断
					}
					else                 //之前的加减乘除弹出来
					{
						s[j] = char(e);
						j++;
					}
				
				} while(StackLen(p) && '('!= char(e));
				Push(&p, ch[i]);
			}
		}
		else if ('*' == ch[i] || '/' == ch[i] || '(' == ch[i])
		{
			Push(&p, ch[i]);
		}
		else if ('#' == ch[i])
		{
			Pop(&p,&e);
			s[j] = char(e);
			j++;
			s[j] = '#';
			break;
		}
		else
		{
			printf("\n出错:输入格式错误!\n");
			break;
		}
		i++;
	}
	return t;	
}
4、主程序实现逻辑
int main()
{
	sqStack s; char e;
	ElemType c, d;
	char a[10];
	char chr;
	int i = 0;
	char ct[100];

	InitStack(&s);
	printf("请输入你的表达式");
	int k = 0;
	scanf("%c", &chr);
	while (chr != '#')
	{
		ct[k] = chr;
		k++;
		scanf("%c", &chr);
	}
	ct[k] = '#';
	k++;

	strcpy(ct,GetInfix(ct));//必须这样
	double t= GetValue(ct, s);

	printf("已经运算完毕%.1f\n", t);
	getchar();
	return 0;
}
5、遇到的问题

1、返回值用 char*,只要不用strcpy得到的值便是乱码;
https://zhidao.baidu.com/question/14732048.html
解决方案:(1)将返回值作为形参传入(2) 用strcpy函数 (3)全局变量
2、注意细节逻辑

完整代码:链接:https://pan.baidu.com/s/1cTwVbTV07xHCcVASRgrwtA
提取码:mx17

你可能感兴趣的:(算法)