知识点2021字符串栈队列安全工程师小米集团链表
描述
IPV4地址可以用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此正号不需要出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。
现在需要你用程序来判断IP是否合法。
数据范围:数据组数:1≤t≤18 1≤t≤18
进阶:时间复杂度:O(n) O(n) ,空间复杂度:O(n) O(n)
输入描述:
输入一个ip地址,保证不包含空格
输出描述:
返回判断的结果YES or NO
示例1
输入:
255.255.255.1000
复制输出:
NO
cc方法00:暴力枚举
/hj090_legal_ip_00_vio_00.cc
// 暴力枚举
#include <iostream>
#include <vector>
using namespace std;
bool check(const string & s)
{
vector<string> strs(0);
string tmp = "";
// 根据分隔符'.'将每个子段切分并缓存
for (int i = 0; i < s.size(); ++i) {
if (s[i] != '.') {
tmp.push_back(s[i]);
} else {
strs.push_back(tmp);
tmp.clear();
}
}
strs.push_back(tmp); // 最后一个.后边的最后一段子串
// 如果解析结果不是4个子段,那就不是合法ip
if (strs.size() != 4) {
return false;
}
for (const string & subStr : strs) {
if (subStr == "") {
return false; // 避免出现空的子段(如.1.2.3)
}
// 避免出现0开头的子段(如01.2.3.8)
if (subStr.size() > 1 && subStr[0] == '0') {
return false;
}
// 计算子段结果前先添加第一个字符
if (subStr[0] – '0' < 0 || subStr[0] – '0' > 9) {
return false;
}
int sum = subStr[0] – '0';
for (int i = 1; i < subStr.size(); ++i) {
sum = sum * 10 + (subStr[i] – '0');
}
if (sum > 255 || sum < 0) {
return false;
}
}
return true;
}
int main()
{
string s;
while (getline(cin, s)) {
cout << (check(s) ? "YES" : "NO") << endl;
}
return 0;
}
cc方法01:stl,inet_pton函数判断是否为合法ip
// stl,inet_pton函数判断是否为合法ip
#include <iostream>
#include <vector>
#include <arpa/inet.h>
using namespace std;
bool check(const string & s)
{
sockaddr_in sa;
// inet_pton这个函数在成功时返回1,失败时返回0
return inet_pton(AF_INET, s.c_str(), &(sa.sin_addr));
}
int main()
{
string s = "";
while (getline(cin, s)) {
cout << (check(s) ? "YES" : "NO") << endl;
}
return 0;
}
cc方法02:stl,stringstream
/hj090_legal_ip_01_stl_01.cc
// stl,stringstream
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
bool check(const string & s)
{
// `stringstream` 提供内存中的字符串流处理能力,允许像操作文件流一样操作字符串。
// 支持输入(从字符串读取)和输出(向字符串写入),使用 `<<` 和 `>>` 操作符进行读写
// 可以自动处理字符串与基本数据类型之间的转换
// 字符串流对象 `ss` 调用构造函数用字符串 `s`, 此时 `ss` 的内容与 `s` 完全一致。
stringstream ss(s);
string tmp;
int cnt = 0;
// getline(ss, tmp, '.')表示从 `ss` 中读取字符,将读取的字符存入 `tmp`
// 当遇到 `.` 字符时停止读取,- 丢弃分隔符 `.`(不存入 `tmp`)- 返回 `true` 表示成功读取一段
// 1. 当遇到流末尾(无分隔符'.')时,`getline` 会读取从当前位置到流结束的所有字符
// – 将读取的内容存入 `tmp`,不触发失败状态**(仍返回true),流状态变为 `eof`(结束状态)
// 2. 后续操作: -下一次调用 `getline` 时,由于流已结束- 直接返回 `false`,终止循环
while (getline(ss, tmp, '.')) {
// int atoi(const char *str);是一个C标准库函数,用于将字符串转换为整数
// c_str()函数是string类的成员函数,用于返回一个指向字符串内部字符数组的指针(以null结尾的C风格字符串)
int num = atoi(tmp.c_str());
// 每一个子段只能是数字不能有其他符号, tmp[0]必须是数字,不能为空或其他
if ((num != 0 && tmp[0] == '0') || !isdigit(tmp[0])) {
return false;
} else if (num < 0 || num > 255) {
return false;
} else {
cnt++;
}
}
// 检测到4个子段且每个子段都是合法的数字
if (cnt != 4) {
return false;
}
return true;
}
int main()
{
string s = "";
while (getline(cin, s)) {
cout << (check(s) ? "YES" : "NO") << endl;
}
return 0;
}
网硕互联帮助中心



评论前必须登录!
注册