本题代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
struct M
{
int a,b;
M(int a=0,int b=0):a(a),b(b){}
}s[50];
stack<M>q;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
string name;
cin>>name;
int k=name[0]-'0';
cin>>s[k].a>>s[k].b;
}
string x;
while(cin>>x)
{
int ans=0;
bool error=false;
int len=x.size();
for(int i=0;i<len;i++)
{
if(isalpha(x[i]))q.push(s[x[i]-'0']);
else if(x[i]==')')
{
M m2=q.top();q.pop();
M m1=q.top();q.pop();
if(m1.b!=m2.a){error=true;break;}
ans+=m1.a*m1.b*m2.b;
q.push(M(m1.a,m2.b));
}
}
if(error)cout<<"error"<<endl;
else cout<<ans<<endl;
}
return 0;
}
首先,做这道题要先了解结构体成员函数的构造与使用,(这个是我的知识盲区,所以看这段代码的时候很懵逼 )
学习这个知识点可以参考一下文章:(写的很好)
结构体构造函数
在这里也简要说明一下:
其实结构体成员函数的最大作用是用于修改结构体其他成员的值。所以利用它可以在一定程度上简化代码。
此题中的stack的用法也是一绝。
我们都知道定义一个栈的常见模板是:stack<类型名>栈名;
而在之前我所认知的类型名仅仅是局限于int,string等类。但此题却把结构体当成了一种类型,栈中所储存的也是以该类结构体的数据。
下面放出结构体的理解:
定义结构体:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
//三种方式:
//1、struct 结构体名 变量名
//2、struct 结构体名 变量名 = {member1,member2,…}
//3、定义结构体时顺便创建变量
结构体属于用户自己定义的数据类型,所以在使用的时候可以这样操作:结构体名 变量名 相当于 int a。
再谈栈是什么:
这是我第一次用STL中的栈来完成题目,所以就在这里聊聊栈到底是什么。
栈(Stack)又称堆栈,是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。
划重点:栈是一种先进后出,后进先出的数据结构。
你可以把栈理解成一个死胡同,只有后面的人出来了,前面的人才能出来。
栈的基础操作模块:
出栈:push
压栈:pop
栈是否为空:empty
栈的大小:size
访问栈顶:top
栈的图示:
在之前我还学过队列:queue
队列与栈式不同的:
基础操作上:
queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。 出队,如例:q.pop();
弹出队列的第一个元素,注意,并不会返回被弹出元素的值。 访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。 判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()
队列相当于两边开口的小巷子,它所遵循的法则是:先进先出,后进后出。
如果觉得抽象可以使用下面的代码,有助于理解:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
queue<int>q;
int main()
{
q.push(1);
q.push(2);
q.push(3);
q.push(4);
q.push(5);
q.push(6);
q.push(7);
q.push(8);
q.push(9);
q.pop();
q.pop();
cout<<q.front()<<endl;
return 0;
}
聊回本题:
其实此题最大的妙点在于这一段代码:
string x;
while(cin>>x)
{
int ans=0;
bool error=false;
int len=x.size();
for(int i=0;i<len;i++)
{
if(isalpha(x[i]))q.push(s[x[i]-'0']);
else if(x[i]==')')
{
M m2=q.top();q.pop();
M m1=q.top();q.pop();
if(m1.b!=m2.a){error=true;break;}
ans+=m1.a*m1.b*m2.b;
q.push(M(m1.a,m2.b));
}
}
if(error)cout<<"error"<<endl;
else cout<<ans<<endl;
}
首先,说一个小细节:string类的变量,如果要统计长度的话,不能用strlen函数,而应该用x.size()或x.length()。他们两者没有差异。
再看一个函数isalphan(x)他的作用是判断x数组内是否全为字母,如果是返回1,不是则返回0;和他相识的是isdigit()函数,他的作用是判断是否全为数字。
之后可以看到这段代码:
M m2=q.top();q.pop();
M m1=q.top();q.pop();
翻译一下就是定义了一个M 类型的结构体。m1,m2是变量名,用于储存结构体。
又因为栈 q 也是M类的,所以从栈顶取出的数据就是一个结构体的全部内容。
q.push(M(m1.a,m2.b));
这段代码就是对结构体成员函数的使用了,就是修改结构体成员的值。