题意
判断给定ip是否合法
方法
内置库
对于这种大量场景地方都会用到的函数,如果是在面向用户生产代码中,尽可能的不要自己实现,而是使用很多人用过有保障的库函数
inet_pton
这个函数在成功时返回1,失败时返回0,所以我们直接调用它即可
代码
#include<bits/stdc++.h>
#include<arpa/inet.h>
using namespace std;
int main(){
string s;
while(getline(cin,s)){
struct sockaddr_in sa;
printf("%s\n",inet_pton(AF_INET, s.c_str(), &(sa.sin_addr))?"YES":"NO");
}
return 0;
}
复杂度分析
时间复杂度: 对于地址,每一位解析都是常数的操作代价,所以时间复杂度为
空间复杂度: 主要消耗在字符串的存储,所以空间复杂度为
手动实现
一个ip实际上是由4个[0,255] 之间的值拼接而成, 所以验证其是否都在范围内即可
以题目的样例255.255.255.1000
为例子
i(当前位置) | p(字符起始) | 操作 |
---|---|---|
- | 0 | 初始化 |
0 | 0 | 非分割符号 |
1 | 0 | 非分割符号 |
2 | 0 | 非分割符号 |
3 | 0 | 是分割符,判断255是否是一个正确的纯数字又在[0,255]以内。处理后,把p设置为i+1=4 |
4 | 4 | 非分割符号 |
5 | 4 | 非分割符号 |
6 | 4 | 非分割符号 |
7 | 4 | 是分割符,判断255是否是一个正确的纯数字又在[0,255]以内。处理后,把p设置为i+1=8 |
8 | 8 | 非分割符号 |
9 | 8 | 非分割符号 |
10 | 8 | 非分割符号 |
11 | 8 | 是分割符,判断255是否是一个正确的纯数字又在[0,255]以内。处理后,把p设置为i+1=12 |
12 | 12 | 非分割符号 |
13 | 12 | 非分割符号 |
14 | 12 | 非分割符号 |
15 | 12 | 非分割符号 |
16 | 12 | 是结束符,判断1000是否是一个正确的纯数字又在[0,255]以内。失败输出NO |
代码
#include<bits/stdc++.h>
#include<arpa/inet.h>
using namespace std;
bool valids(const char *s,int n){
if(n == 0)return false;
if(s[0] == '0' && n > 1)return false; // 前导零
int v = 0;
for(int i = 0;i<n;i++){
if(!isdigit(s[i]))return false;
v*=10;
v+=s[i]-'0';
}
return v >= 0 && v <= 255;
}
void work(string &s){
int n = s.length();
int p = 0; // 字符串 起始位置
int cnt = 0;
for(int i=0;i<=n;i++){
if(s[i] == '.' || s[i] == '\0'){
if(!valids(s.c_str() + p,i-p)){
printf("NO\n");
return ;
}
p = i+1; // 下一个开始位置
cnt ++;
}
}
printf("%s\n",cnt == 4?"YES":"NO"); // 4位
}
int main(){
string s;
while(getline(cin,s)){
work(s);
}
return 0;
}
复杂度分析
时间复杂度: 每一位解析都是常数的操作代价,所以时间复杂度为
空间复杂度: 主要消耗在字符串的存储,所以空间复杂度为