7/4(读优和写优,预处理器)

1.关于读优和写优

  在c++中,普通的cin,cout,printf,scanf在遇到一些特别大的数据时,效率不高,可能导致程序运行超时。另外,在面对__int128(可以存储正负2^128大小的整数)这样无法通过常规的输入输出进行读写的数据类型,也需要我们手写读入和输出。总之,在一些情况下,进行手写读优写优能使程序更加完善
  代码

点击查看代码
inline void read(int &n){//读优 int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } n=x*f; } inline void print(int n){//写优 if(n<0){ putchar('-'); n*=-1; } if(n>9) print(n/10); putchar(n % 10 + '0'); }
  可以看出,读优写优是根据getchar和putchar等函数的高效来设计的。在遇到要求我们输出较多数据时,可以采用此方法。

2.关于余数

  在模运算中,有时会遇到一个负数模另一个数的情况,当然,这样会直接得到该负数本身,若要得到正确结果,将负数加n(视情况决定其大小),再进行运算

3.预处理器(2022联合省选)

  题目大意:给定一个代码,要求根据其中的宏定义进行相应的宏展开并进行输出
1.既然是要求宏定义和宏展开后的结果一一对应,自然想到用map来存储字符串和字符串间的对应情况
2.注意到题目中提到了如下的情况:多次展开,递归展开。这两种情况处理起来是比较棘手的。这两种情况都是可以通过递归函数来进行处理的,在处理过程中记得用一个map记录某个字符串是否已经被展开过,以此判断是否存在递归展开的情况。在用该map递归处理时,应该回溯(因为只用关心递归树上的从根节点出发的一条路径即可)
3.在宏展开的过程中,有可能遇到展开的结果中含有空格等非法字符的情况,因此需要把这些非法字符和合法的字符串区分开来(这一点也是我觉得比较难写的。。在将合法字符串和非法字符串分开的过程中,要记录下标,还要想好substr怎么用最好,更要注意当前处理的字符串状态的转移(合法到非法,非法到合法))
4.关键是要把题目理解清楚。。在做这个题时我就看掉了题目中关于非法字符的说明,导致我认为合法字符和非法字符之间一定有空格分隔,就没有去处理第三条所提到的情况,于是就失分了。。

点击查看代码
#include<bits/stdc++.h> using namespace std; const int MAXN = 100; string s[MAXN + 5]; map<string,string> m; map<string,bool> vis; string c; int n,cnt; bool check(char a){ if(a >= '0' && a <= '9')return 1; if(a >= 'a' && a <= 'z')return 1; if(a >= 'A' && a <= 'Z')return 1; if(a == '_')return 1; return 0; } string out[MAXN + 5]; string change(string a){//多次展开的处理 string now[MAXN]; int pos = 0,cntt = 1,state = 0;; for(int i = 0; i < a.size(); i++){ if(!check(a[i])){ if(state == 0){ state = -1; pos = i; } else if(state == 1){ string b = a.substr(pos,i - pos); now[cntt++] = b; state = -1; pos = i; } } else{ if(state == 0){ state = 1; pos = i; } else if(state == -1){ string b = a.substr(pos,i - pos); now[cntt++] = b; state = 1; pos = i; } } } now[cntt] = a.substr(pos,a.size() - pos); string p,ans; for(int i = 1; i <= cntt; i++){ p = now[i]; if(m.find(now[i]) != m.end()){ if(vis.find(m[now[i]]) == vis.end() || (vis.find(m[now[i]]) != vis.end() && vis[m[now[i]]] == 0)){ vis[m[now[i]]] = 1; p = change(m[now[i]]); vis[m[now[i]]] = 0;//回溯一下,因为只需要关注当前搜索路径中是否存在递归展开的情况 } } ans += p; } return ans; } int main(){ // freopen("preprocessor.in","r",stdin); // freopen("preprocessor.out","w",stdout); cin >> n; string h; getline(cin,c);//读空行 cnt = 1; for(int i = 1; i <= n; i++){ getline(cin,s[i]);//读入 if(s[i][0] == '#' && s[i][1] == 'd'){ for(int j = 8; j < s[i].size(); j++){ if(s[i][j] == ' '){ string a = s[i].substr(8,j - 8); string b = s[i].substr(j + 1,s[i].size() - j - 1); m[a] = b; puts(""); break; } } } else if(s[i][0] == '#' && s[i][1] == 'u'){ for(int j = 7; j < s[i].size(); j++){ if(s[i][j] == ' '){ string a = s[i].substr(7,j - 7); m.erase(a); puts(""); break; } } } else{ int state = 0,pos;//-1表示处理非标识型字符串,1表示处理标识型字符串 cnt = 1; for(int j = 0; j < s[i].size(); j++){ if(!check(s[i][j])){ if(state == 0){ state = -1; pos = j; } else if(state == 1){ string a = s[i].substr(pos,j - pos); out[cnt++] = a; state = -1; pos = j; } } else{ if(state == 0){ state = 1; pos = j; } else if(state == -1){ string a = s[i].substr(pos,j - pos ); out[cnt ++] = a; state = 1; pos = j; } } } out[cnt] = s[i].substr(pos,s[i].size() - pos); for(int j = 1; j <= cnt; j++){ if(m.find(out[j]) != m.end()){ vis[out[j]] = 1; cout << change(out[j]); } else cout << out[j]; } puts(""); } } }

__EOF__

本文作者Never Gonna Give You Up!
本文链接https://www.cnblogs.com/CZ-9/p/16444545.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   腾云今天首飞了吗  阅读(442)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示