您的位置:首页 > 其它

栈的应用

2016-05-17 13:01 447 查看
思路:

先将字符串进行化简——多位整数,单位整数,浮点数和字符分开

构造一个结构体类型的数组s,存储化简后的中缀表达式

构造一个结构体类型的栈,进行转换

构造一个结构体类型的数组l,存储后缀表达式
构造一个结构体类型的栈,计算后缀表达式

一.存储

gets比较方便输入,扫描字符串,将字符串存入到s中;


二.中缀表达式转后缀表达式

扫描中缀表达式
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈


三.后缀表达式输出

<pre name="code" class="cpp">设置一个栈,开始时,栈为空;
然后从左到右扫描l中的后缀表达式,若遇操作数,则进栈;
若遇运算符,则从栈中退出两个元素,运算后的结果再进栈,直到后缀表达式扫描完毕。
此时,栈中仅有一个元素,即为运算的结果。




/*********************************************************
1.支持多位正整数,正浮点数
2.支持加减乘除
3.支持空格
4.支持回车空输入
5.支持多次输入
6.除以0检错
7.支持表达式合法检测
:首末不能有字符(可以有'('或')')
:括号必须成对
:字符不能连续出现
:左括号的左边不能为数字,右边不能为符号
:右括号的左边不能为符号,右边不能为数字
//尚未解决
:负数运算
*********************************************************/


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <functional>
using namespace std;

#define Max_ 0X3f3f3f3f
int i = 0;
int j = 0;
int k = 0;
int m = 0;
int zuo;
int you;
int begin;
int end = Max_;
int illegal;
char in[Max_] = {0};
struct sta
{
int order;
int flag = 0;//1为int,2为float,3为char
int data1;
double data2;
char data3;
}s[1000],out,l[1000];
stack <sta> hello;
stack <sta> world;
//判断是否为数字
int number(char c)
{
if ((c>='0'&&c<='9')||(c=='.'))
return 1;
else
return 0;
}
//判断是否为合法字符
int mark(char c)
{
if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')
return 1;
else
return 0;
}
//判断结构体是否为存数的结构体
int shu(struct sta c)
{
if((c.flag == 1)||(c.flag == 2))
return 1;
else
return 0;
}
//判断结构体是否为存符号的结构体
int fu(struct sta c)
{
if(c.flag == 3)
return 1;
else
return 0;
}

//删除空格
void delete_space()
{
char c;
for (int i = 0; i < strlen(in); i += 1)
{
if (in[i] == ' ')
{
int j;
for (j = i; j < strlen(in)-1; j += 1)
{
in[j] = in[j+1];
}
in[j] = '\0';
}
}
}

void print(struct sta r)
{
if(r.flag == 1){
printf("%d",r.data1);
}
else if(r.flag == 2){
printf("%lf",r.data2);
}
else if(r.flag == 3){
printf("%c",r.data3);
}
}

void test()
{
for(int j = 0;j < k;j++)
{
print(s[i]);
}
printf("\n");
}

//多位数或浮点数的处理
void deal(int sta,int en)//youwenti
{
//printf("%d%d\n",sta,en);//start end ok
int fla = 0,point;
for(int i = sta;i<=en; i++)//区分浮点数还是多位数,ok
{
if(in[i] == '.'){
fla =  1;
point  = i;
break;
}
}
if(fla)//浮点数
{
//printf("Fudianshu\n");
double sum = 0;
for(int j = sta;j<point;j++){
sum += (in[j]-'0')*(float)pow(10,point-j-1);
}
for(int j = point+1;j<=en;j++){
sum += (in[j]-'0')*(float)pow(10,point-j);
}
s[k].flag = 2;
s[k].data2 = sum;
//        printf("%d ",k);
//        printf("%lf\n",s[k].data2);
s[k].order = k;
k++;
}
else//多位整数
{
//printf("Duoweizhengshu");
int sum = 0;
int a = en-sta;
for(int j = sta;j <= en;j++)
{
sum += (in[j]-'0')*(float)(pow(10,a));
//printf("%d\n",sum);
a--;
}

s[k].flag = 1;
s[k].data1 = sum;
//        printf("%d %d\n",k,s[k].data1);
s[k].order = k;
k++;
}
return ;
}

void store()//存储到s
{
memset(s,0,sizeof(s[0]));
begin = 0;
for (i = 0; i < strlen(in); i += 1)
{
if(mark(in[i])){//字符
begin = i+1;
s[k].flag = 3;
s[k].data3 = in[i];
//printf("%c\n",s[k].data3);
k++;
}
else if(number(in[i])){//数字
for(int j = i+1;j<=strlen(in);j++){
if(mark(in[j])||(j==strlen(in))){
i = j-1;//下位调到字符继续搜索
end = j-1;
break;
}
}
if(end-begin){
deal(begin,end);
}
else{//单位整数ok
s[k].flag = 1;
s[k].data1 = (in[i]-'0');
//printf("%d %d\n",k,s[k].data1);
k++;
}
}
}
return ;
}

void judge()
{
for(int j = 0; j < k; j++)//判断括号
{
if(fu(s[j])){
if(s[j].data3=='(')
{
zuo++;//右边不能为字符
if((j+1<k)&&((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/')))
{
illegal = 2;
return ;
}
if((j-1>=0)&&(shu(s[j-1])))//左边不能为数字
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
if(((j+1<k)&&(s[j+1].data3==')'))||(j==k-1))//空格中不能为空,不能放鸽子;不能为尾
{
illegal = 2;
return ;
}
}
else if(s[j].data3==')')
{
you++;//左边不能为字符
if((j-1>=0)&&((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/')))
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
if(((j+1<k)&&(shu(s[j+1])))||(j==0))//右边不能为数字;不能为首
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
}
else if((s[j].data3=='+')||(s[j].data3=='-')||(s[j].data3=='*')||(s[j].data3=='/'))
{
if((j==0)||(j==k-1))//首尾不能为字符
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
else if((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/'))
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
else if((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/'))
{
//printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
}
}
}
if(zuo!=you){
printf("Ilegal expression,please input again\n");
illegal = 2;
return ;
}
}

void in_data()//ok
{
memset(in,0,sizeof(in[0]));
illegal = 0;
k = 0;
zuo = 0;
you = 0;
printf("Please input:");
gets(in);//输入
delete_space();
if(strlen(in)==0){//不断回车,跳过
illegal =  3;
return ;
}
if(in[0] == '#'){//结束符
illegal = 1;
return ;
}
for(i = 0;i < strlen(in);i++)
{
if(!mark(in[i]) && !number(in[i])){//
printf("Wrong inputs!\n");
illegal =  3;
return ;
}
}
store();//存储
judge();//表达式的判断
//printf("%d",k);
return ;
}

int nless(char a,char b)//a>=b
{
if((a=='(')&&(b!='(')){
return 0;
}
else if(a=='+'||a=='-'){
if(b=='*'||b=='/'){
return 0;
}
}
else return 1;
}

void middle_later()//扫描s,l赋值有问题
{
memset(l,0,sizeof(l[0]));
while(!hello.empty()){
hello.pop();
}
m = 0;
printf("Postfix Expression:");
for(int j = 0;j < k; j++)
{
//栈为空时,遇到运算符直接入栈
if(hello.empty()&&fu(s[j])){
hello.push(s[j]);
}
//遇到操作数,直接输出
else if(shu(s[j])){
print(s[j]);
l[m] = s[j];
m++;
printf(" ");
}
//遇到左括号,入栈
else if(fu(s[j])&&s[j].data3 == '('){
hello.push(s[j]);
}
//遇到右括号,执行出栈操作,直至弹出的栈为左括号,左括号不输出
else if(fu(s[j])&&s[j].data3 == ')'){
while(!hello.empty())
{
out = hello.top();
if(out.data3 != '('){
print(out);
l[m] = out;
m++;
printf(" ");
hello.pop();
}
else{
hello.pop();
break;
}
}
}
//遇到加减乘除,弹出所有优先级不小于该运算符的栈顶元素,然后将该运算符入栈
else if(fu(s[j]))
{
while(!hello.empty())
{
out = hello.top();
if(nless(out.data3,s[j].data3))
{
print(out);
l[m] = out;
m++;
printf(" ");
hello.pop();
}
else
break;
}
hello.push(s[j]);
}
}
while(!hello.empty())
{
out = hello.top();
print(out);
l[m] = out;
m++;
printf(" ");
hello.pop();
}
printf("\n");
//    for(int j = 0; j < k; j++)
//    {
//        print(l[j]);
//    }
//    printf("\n");
}

double data(struct sta c)
{
if(c.flag==1)
return c.data1;
else if(c.flag==2)
return c.data2;
}

void with(struct sta b,char c,struct sta a)
{
struct sta d;
double ans = 0;
switch(c)
{
case '+':ans = data(b)+data(a);break;
case '-':ans = data(b)-data(a);break;
case '*':ans = data(b)*data(a);break;
case '/':
{
if(data(a)==0)
{
printf("No ends,sorry\n");
illegal =  2;
return ;
}
ans = data(b)/data(a);
break;
}
}
d.flag = 2;
d.data2 = ans;
world.push(d);
return ;
}

void later_out()
{
struct sta a,b;
while(!world.empty()){
world.pop();
}
for(int j = 0; j < m; j++)
{
//print(l[j]);//ok
if(shu(l[j])){
world.push(l[j]);
}
else if(fu(l[j]))
{
a = world.top();
world.pop();
b = world.top();
world.pop();
with(b,l[j].data3,a);
if(illegal==2)
return ;
}
}
printf("Answer:");
print(world.top());
printf("\n\n");
return;
}

int main(int argc, char const* argv[])
{
while (1)
{
//输入及存储
in_data();
if(illegal == 1)    break;
if(illegal == 2){printf("Ilegal expression,please check again\n");continue;}
if(illegal == 3)    continue;
//中缀转后缀
middle_later();
//后缀计算输出
later_out();//youcuowu
if(illegal == 2)    continue;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息