sscanf小技巧-洛谷P7911 网络连接
序言
本题解来源:本蒟蒻上课摸鱼 (别学我)
最近学了一个挺好用的函数——sscanf(),结合洛谷P7911 网络连接讲一下。
(点击查看题目)
推荐几首纯音乐,拿走不谢↓
- Bloom of Youth
- Windy Hill
- Love Is Gone
- 所念皆星河
- 这题其实挺简单的, 让不少人 (包括本蒟蒻) 头大并WA掉的主要是这几点:
1 . 把数字和字符 拆开 分开判断
2 . 判断前导0
3 . 查找、判断重复
4 . …
题目分析
- 本题为洛谷 P7911 网络连接
- 题目虽然比较长,但比较简单,耐心看很容易就能看懂
- 输入类型、地址↓
string s, t;
cin>>s>>t;
- 若地址不符合要求,输出“ERR”,判断下一个↓
if(!check(t)){
cout<<"ERR"<<endl;
continue;
}
- 若为服务机(Server)↓
if(s == "Server")
- 若地址没有出现过,输出“OK”↓
if(server[t] == 0){
server[t] = i;
cout<<"OK"<<endl;
}
- 若与先前某台已经成功建立连接的服务机的地址相同,输出“FAIL”↓
else{
cout<<"FAIL"<<endl;
}
- 若为客户机(Client)↓
else
- 若与先前某台已经成功建立连接的服务机的地址相同,输出服务机的地址↓
if(server[t] > 0)
cout<<server[t]<<endl;
- 若找不到这样的服务机,则这台客户机无法成功加入连接↓
else
cout<<"FAIL"<<endl;
正文(— _ —)
一、介绍一个函数—— sscanf()
(别看我,我没打错,就是 sscanf
)
头文件 (万能头)↓
#include <bits/stdc++.h>
sscanf 的用法
sscanf
的用法类似一个字符串格式化工具
- 从一个字符串中读进与指定格式相符的数据
char ch[101]; sscanf("12345", "%s", ch); //读入字符串 cout<<ch; //输出12345
- 取指定长度的字符串
char ch[101]; sscanf("12345", "%3s", ch); //取指定长度的字符串 cout<<ch; //输出123
- 取到指定字符为止的字符串
char ch[101]; sscanf("12345abcd", "%[^a]", ch); //读到a cout<<ch; //输出12345
- 取到指定字符集为止的字符串
char ch[101]; sscanf("123m45abcd", "%[^a-z]", ch); //读到m cout<<ch; //输出123
- 补充介绍一个
sprintf()
·既然sscanf
是把字符串拆开,那sprintf
就是把字符串拼起来
这样用↓
char ch[101];
sprintf(ch,"%d.%d.%d.%d:%d",1,2,3,4,5);
cout<<ch; //输出 1.2.3.4:5
二、介绍一种数据结构——map
map
是啥??
就是一个能以任意数据结构为下标的数组。
所以怎么用??
举个栗子:我们要建一个以字符串即 string
为下标、存 int
的名为 a
数组,就可以这样写↓
map<string, int>a;
那么这样存值↓
string str = "-_-";
a[str] = 4;
这样我们就可以直接判断地址是否出现过
是不是很神奇?
三、一个判断前导0的小方法
我们现在已经有了 sscanf()
和sprintf()
,就可以把字符串里的数字拆出来,前导0就会省略,再拼回去,与原字符串比较,如果不同就是有前导0
四、讲完技巧,开始写代码
- 这题思路十分的简单,直接模拟就行
直接上标程↓
#include<bits/stdc++.h>
using namespace std;
int n;
map<string, int>server;
bool check(string ip){
int t[6] = {0, -1, -1, -1, -1, -1};
int cnt = sscanf(ip.c_str(), "%d.%d.%d.%d:%d", &t[1], &t[2], &t[3], &t[4], &t[5]);
if(cnt != 5) return 0;
for(int i=1;i<=4;i++)
if(t[i] < 0 || t[i] > 255) return 0;
if(t[5] < 0 || t[5] > 65536) return 0;
char ch[50];
sprintf(ch, "%d.%d.%d.%d:%d", t[1], t[2], t[3], t[4], t[5]);
if(ip != string(ch)) return 0;
return 1;
}
int main(){
freopen("network.in", "r", stdin);
freopen("network.out", "w", stdout);
cin>>n;
string s, t;
for(int i=1;i<=n;i++){
cin>>s>>t;
if(!check(t)){
cout<<"ERR"<<endl;
continue;
}
if(s == "Server"){
if(server[t] == 0){
server[t] = i;
cout<<"OK"<<endl;
}
else{
cout<<"FAIL"<<endl;
}
}
else{
if(server[t] > 0)
cout<<server[t]<<endl;
else
cout<<"FAIL"<<endl;
}
}
return 0;
}
写在最后
感谢耐心看完这136行的题解!
希望你们能学到东西 (# ^ . ^ #)
( 没用的小知识又增加啦 )