UVA442 结构体成员函数+stack

本题代码:

#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));

这段代码就是对结构体成员函数的使用了,就是修改结构体成员的值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值