Bootstrap

中缀表达式转后缀表达式

下面我来讲解电脑里的中缀表达式转后缀表达式,完成它我运用了栈,我们习惯的数学表达式叫中缀表达式 例:1+(8-5)*5但是中缀表达式计算机读不了,它要将中缀表达式转换为后缀表达式才能读,例:中缀表达式转后缀b表达式  1+2*3=>1 2 3 * +

中缀转后缀:

对于数字:直接输出。

对于符号:

1、左括号,直接进栈。

2、运算符号,与栈顶符号进行优先级比较,若栈顶符号极低,此符号进栈(默认栈顶元素是左括号,左括号优先级最低);若栈顶括号优先级不低,栈顶符号弹出并输出,之后栈。

3、右括号:将栈顶符号弹出并输出,直到匹配到左括号

4、遍历结束,将栈顶符号弹出并输出

#include"liststack.h"//引用已写好的栈文件
using namespace std;

typedef struct PERSON
{
	Linknode node;
	char* name;
	int index;
}Person;

//判断数字
int JudgeNum(char c)
{
	return c >= '0' && c <= ' 9';
}
//判断左括号
int JudgeLeft(char c)
{
	return c=='(';
}
//判断右括号
int JudgeRight(char c)
{
	return c == ')';
}
//判断符号
int JudgeSymbol(char c)
{
	return c == '+' || c == '-' || c == '*' || c == '/';
}

int CompareSymbol(char c)
{
	if (c=='-'||c=='+')
	{
		return 1;
	}
	if ( c=='*'||c=='/')
	{
		return 2;
	}
	return 0;
}
Person* Myper(char*p)
{
	Person*per = (Person*)malloc(sizeof(Person));
	per->name = p;
	return per;
}

void RightOperator(LinkStack* stack, char*p) 
{
	//右括号:将栈顶符号弹出并输出,直到匹配到左括号
	while (Size_LinkStack(stack)>0)
	{
		//取出栈顶元素
		Person *per = (Person*)Top_LinkStack(stack);
		if (JudgeLeft((*per->name)))
		{
			Pop_LinkStackSe(stack);
			free(per);
			return;
		}
		printf("%c", *(per->name));
		Pop_LinkStackSe(stack);
		free(per);
	}
}

void  SymbolOperator(LinkStack* stack,char*p)
{
	/*运算符号,与栈顶符号进行优先级比较,若栈顶符号极低,此符号进栈(默认栈顶元素是左括号,左括号优先级最低)
	;若栈顶括号优先级不低,栈顶符号弹出并输出, 之后进栈。*/
	Person *per = (Person*)Top_LinkStack(stack);
	if (per == NULL)
	{
		Push_LinkStack(stack, (Linknode*)Myper(p));
		return;
	}
	while (Size_LinkStack(stack)>0)
	{
		if (CompareSymbol(*(per->name))<CompareSymbol(*p))
		{
			Push_LinkStack(stack, (Linknode*)Myper(p));
			return;
		}
		else
		{
			printf("%c", *(per->name));
			Pop_LinkStackSe(stack);
			Push_LinkStack(stack, (Linknode*)Myper(p));
			return;
		}
	}
}

void main()
{
	LinkStack* stack = Init_LinkStack();//栈的初始化
	char*str = "8 + (3 - 1) * 5 "; //8 + (3 - 1) * 5     831-5*+
	char*p = str;

	while (*p!='\0')
	{
		if (JudgeNum(*p))
		{
			printf("%c", *p);
		}
		if (JudgeLeft(*p))
		{
			Push_LinkStack(stack, (Linknode*)Myper(p));
		}
		if (JudgeRight(*p))
		{
			RightOperator(stack, p);
		}
		if (JudgeSymbol(*p))
		{
			SymbolOperator(stack, p);
		}
		p++;
	}
	while (Size_LinkStack(stack)>0)
	{
		Person *per = (Person*)Top_LinkStack(stack);
	    printf("%c", *(per->name));
		Pop_LinkStackSe(stack);
		free(per);
	}
	cout << endl;
}

运用结果:

 

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;