数据结构——栈的应用

数据结构——栈的应用

1.就近匹配
规则如下:

  • 如果是左括号,则入栈;
  • 如果是右括号,若栈顶元素是其对应的左括号,则退栈,若不是对应的左括号,则结论为括号不匹配;
  • 当表达式结束后,若栈为空,则表明表达式中括号匹配;否则表明表达式中括号不匹配。
#include"linkstrack.cpp"
#include<string>
int match(string &str )
{
	LinkStrack<char> ls;
	for (int i = 0; i < str.size(); i++)
	{
		switch (str[i])
		{
		case '(':
			ls.push_linkstrack(str[i]);
			break;
		case ')':
			if (ls.size == 0 || ls.GetTop_linkstrack() != '(')
			{
				return -1;
			}
			ls.pop_linkstrack();
			break;
		case '{':
			ls.push_linkstrack(str[i]);
			break;
		case '}':
			if (ls.size == 0 || ls.GetTop_linkstrack() != '{')
			{
				return -1;
			}
			ls.pop_linkstrack();
			break;
		case '[':
			ls.push_linkstrack(str[i]);
			break;
		case ']':
			if (ls.size == 0 || ls.GetTop_linkstrack() != '[')
			{
				return -1;
			}
			ls.pop_linkstrack();
			break;
		default:
			break;
		}
	}
	if (ls.GetTop_linkstrack() == NULL)
	{
		return 1;
	}
}
int main()
{
	string str = { "(){[()][]}[()]" };
	int flag=match(str);
	if (flag==1)
	{
		cout << "完美匹配" << endl;
	}
	if (flag==-1)
	{
		cout << "不能完全匹配" << endl;
	}
	system("pause");
	return 0;
}
/*---------------单括号------------------*/
//string str = { "2+6*((1+3))-4*(5-2))" };
//LinkStrack<char> ls;
//for (int i = 0; i < str.size(); i++)
//{
//	if (str[i] == '(')
//	{
//		ls.push_linkstrack(str[i]);
//	}
//	if (str[i] == ')')
//	{
//		if (ls.GetTop_linkstrack() == '(')
//		{
//			ls.pop_linkstrack();
//		}
//		else
//		{
//			ls.push_linkstrack(str[i]);
//			break;
//		}
//	}
//}
//if (ls.GetTop_linkstrack() == NULL)
//{
//	cout << "完美匹配" << endl;
//}
//else
//{
//	cout << "不能完全匹配" << endl;
//}

2.中缀转后缀
规则如下:

  • 若是’(’,则入栈
  • 若是操作数,则将其输出
  • 若是操作符,若其优先级比栈顶元素优先级高,则入栈;否则,栈顶元素退栈输出,再与新的栈顶元素进行比较,重复此步骤
  • 若是’)’,将栈中元素依次输出知道碰到’(’,然后退栈,消除一对括号
  • 当遇到‘=’,开始退栈输出,直到空
#include"linkstrack.cpp"
#include<string>
int text(char c)
{
	if (c=='*'||c=='/')
	{
		return 2;
	}
	else if(c=='+'||c=='-')
	{
		return 1;
	}
	else if(c == '(')
	{
		return 0;
	}
}
void work(string &str)
{
	LinkStrack<char> ls;
	for (int i = 0; i < str.size(); i++)
	{
		if (str[i]>='0'&&str[i]<='9'||str[i]=='.')
		{
			cout << str[i];
		}
		else if (str[i]=='(')
		{
			ls.push_linkstrack(str[i]);
		}
		else if(str[i]=='*'|| str[i] == '/' || str[i] == '+' || str[i] == '-')
		{
			if (text(str[i])>text(ls.GetTop_linkstrack())||ls.size==0)
			{
				cout << " ";
				ls.push_linkstrack(str[i]);
			}
			else
			{
				cout <<" "<< ls.GetTop_linkstrack();
				ls.pop_linkstrack();
				ls.push_linkstrack(str[i]);
				cout << " ";
			}
			
		}
		else if(str[i] == ')')
		{
			while (ls.GetTop_linkstrack()!='(')
			{
				cout << " " << ls.GetTop_linkstrack();
				ls.pop_linkstrack();
			}
			ls.pop_linkstrack();
		}
		if (str[i] == '=')
		{
			while (ls.size != 0)
			{
				cout << " " << ls.GetTop_linkstrack();
				ls.pop_linkstrack();
				cout << " ";
			}
		}
	}
}
int main()
{
	string str = {"12*(6/2-0.5)="};
	work(str);
	system("pause");
	return 0;
}

3.后缀求值
规则如下:

  • 若读到操作数,则入栈
  • 若是读到运算符,则将栈顶两个元素弹出,后弹出的操作数为被操作数,先弹出的为操作数,将操作的结果入栈
  • 若读到空格,则跳过它
  • 表达式扫描完毕,栈中剩一个 数,即表达式的结果值。
#include"linkstrack.cpp"
#include<string>
double computer(double &a, double &b,char &c)
{
	switch (c)
	{
	case '+':
		return a + b; break;
	case '-':
		return a - b; break;
	case '*':
		return a * b; break;
	case '/':
		return a / b; break;
	default:
		break;
	}
}
//void work0(string &str)
//{
//	LinkStrack<int> ls;
//	for (int i = 0; i < str.size(); i++)
//	{
//		if (str[i]>='0'&&str[i]<'10')
//		{
//			int temp = str[i] - '0';
//			ls.push_linkstrack(temp);
//		}
//		else if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
//		{
//			int a = ls.GetTop_linkstrack();
//			ls.pop_linkstrack();
//			int b = ls.GetTop_linkstrack();
//			ls.pop_linkstrack();
//			int result = computer(b,a,str[i]);
//			ls.push_linkstrack(result);
//		}
//	}
//	cout << ls.GetTop_linkstrack() << endl;
//}
double spellnum(string &str,int &i)
{
	double num1=0,num2=0,num;
	int j = 0;
	while (str[i]>='0'&&str[i]<'10')
	{
		num1 = num1 * 10 + str[i++] - '0';
	}
	if (str[i]=='.')
	{
		i++;
		while (str[i] >= '0'&&str[i] < '10')
		{
			num2 += (str[i++] - '0')*1.0 / pow(10.0, ++j);
		}
	}
	return num=num1+num2;
}
void work2(string &str)
{
	LinkStrack<double> ls;
	for (int i = 0; i < str.size(); i++)
	{	
		if (str[i] >= '0'&&str[i] < '10')
		{
			double top = spellnum(str, i);
			ls.push_linkstrack(top);
		}
		else if (str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
		{
			double a = ls.GetTop_linkstrack();
			ls.pop_linkstrack();
			double b = ls.GetTop_linkstrack();
			ls.pop_linkstrack();
			double result = computer(b, a, str[i]);
			ls.push_linkstrack(result);
		}
	}
	cout << ls.GetTop_linkstrack() << endl;
}
int main()
{
	string str = { "12 6 2 / 0.5 - *" };
	//work1(str);一位数
	work2(str);//多位数并包含小数点
	system("pause");
	return 0;
}

操作数的拼数为重点

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值