字符串表达式的计算(c++版)

一.字符串表达式的解析

      z字符串表达式在栈结构的应用中是一个非常典型的列子,其算法设计思维充分的利用了栈的特性.

     类如: "1+8*9+(4+5)*7" 完成字符串表达式的计算主要分为2个步骤;

    1. 将中缀转化为后缀

              按照(*/+-)的优先级;分别创建2个栈用来贮存数字和符号,从第一个元素遍历,遇到数字进入数字栈,遇到符号进入符号栈,如果入栈符号的优先级小于等于栈顶符号的优先级,则将栈顶元素压入数字栈中,重复上述动作;最后如果符号栈有剩余则全部进入数字栈;

       2.将后缀表达式计算

     遍历全部元素,遇到数字数字压入新栈中,遇到符号将此符号作为前面2个数字的运算符,计算结果压入新栈,直到计算完成

原理图:

                          字符串表达式的计算(c++版)_第1张图片

二.源代码的实现

        

#include 
#include 
#include  
#include 
const int  SIZE = 100; // 栈的初始容量
const int  ADDSIZE = 5; // 栈的单位增加容量
using namespace std;// 命名空间
const int INF = -0xfffffff;// 用于空栈时防止尴尬,返回一个不能读取的地址,让读取的人尴尬;
template 
struct Strack
{
	T *top;// 栈顶的指针
	T *base;// 栈底的指针
	int strackSize;//栈容量
	void init()//栈的初始化
	{
		base = (T *)malloc(SIZE * sizeof(T));//分配内存
		top = base;
		strackSize = SIZE;
	}

	T Top()
	{// 返回栈顶元素
		if (top == base)
			return INF;// 返回尴尬地址
		return *(top - 1);
	}

	bool pop()
	{// 删除栈顶元素
		if (top == base)
			return false;
		top--;
		return true;
	}

	void push(T x)
	{//栈顶插入元素
		if (isPull()) {//如果内存不够重新分配内存
			base = (T *)realloc(base, (strackSize + ADDSIZE)*(sizeof(T)));
			top = base + strackSize;
			strackSize += ADDSIZE;
		}
		*top++ = x;
	}

	bool isEmpty()
	{//判断栈是否为空
		if (top == base)
			return true;
		return false;
	}

	bool isPull()//判满函数
	{
		if (top - base == strackSize)// 一次push一个所以当top - base = strackSize时满
			return true;
		else
			return false;
	}
};

int compareNumber(char x)//用来比较符号的优先级
{
	if (x == '+' || x == '-')
		return 0;
	if (x == '*' || x == '/')
		return 1;
	return -1;
}

void change(char *mid, char *suxfix)//中缀表达式转换为后缀表达式     
{
	int i = 0, len = strlen(mid), mid_index = 0;
	char c;
	StrackintElements;// int数据集
	intElements.init();
	intElements.push('#');// 特殊符号用来区分元素
	while (i < len)
	{
		if (mid[i] == '(')
		{
			intElements.push(mid[i]);
			i++;
		}
		else if (mid[i] == ')')
		{
			while (intElements.Top() != '(')
			{
				suxfix[mid_index++] = intElements.Top();
				suxfix[mid_index++] = ' ';
				intElements.pop();
			}
			intElements.pop();
			i++;
		}
		else if (mid[i] == '+' || mid[i] == '-' || mid[i] == '/' || mid[i] == '*')
		{
			while (compareNumber(intElements.Top()) >= compareNumber(mid[i]))
			{
				suxfix[mid_index++] = intElements.Top();
				suxfix[mid_index++] = ' ';
				intElements.pop();
			}
			intElements.push(mid[i]);
			i++;
		}
		else if (mid[i] >= '0'&&mid[i] <= '9')
		{
			while (mid[i] >= '0'&&mid[i] <= '9')
			{
				suxfix[mid_index++] = mid[i];
				i++;
			}
			suxfix[mid_index++] = ' ';
		}
		else
		{

		}
	}
	while (intElements.Top() != '#') {
		suxfix[mid_index++] = intElements.Top();
		suxfix[mid_index++] = ' ';
		intElements.pop();
	}
	suxfix[mid_index] = 0;
}

double countSuxfix(char *suxfix)//计算后缀表达式   suxfix后缀表达式
{
	int len = strlen(suxfix);
	double x;
	Strack intElements;
	intElements.init();
	int i = 0;
	while (i= '0'&&suxfix[i] <= '9') {
				x = x * 10 + suxfix[i] - '0';// 连续2个数,第一个*10,以此类推
				i++;
			}
		}
		}

		intElements.push(x);
	}
	return intElements.Top();
}
int main()
{
	char str[1000];
	char newStr[1000];
	scanf("%s", str);
	change(str, newStr);
	cout << newStr << endl;
	cout << countSuxfix(newStr) << endl;
	return 0;
}

--------------------------------------------------------------------------over-----------------------------------------------------------------------------------------

你可能感兴趣的:(字符串表达式的计算(c++版))