题解 | 识别有效的IP地址和掩码并进行分类统计
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream>
#include <sstream>
#include<vector>
#include<string>
#include<unordered_set>
using namespace std;
unordered_set<int>uset{128,192,224,240,248,252,254,255};
//用来分隔字符串,转化成数字
void cut(string& s, vector<int>& nums) {
string t;
int n = 0;
for (int i = 0; i < s.size() && n <= 4; i++) {
if (s[i] >= '0' && s[i] <= '9') {
t.push_back(s[i]);
}
if (s[i] == '.' || i == s.size() - 1) {
if (!t.empty())
nums[n] = stoi(t);
else {
nums[n] = -1;
}
t.clear();
n++;
}
}
if (s[s.size() - 1] == '.')nums[3] = -1;特殊情况之如果最后是.需要手动加上nums3
}
int IPwhere(string& first) {
vector<int>nums(4);
nums.clear();
cut(first, nums);
for (int i=0;i<4;i++) {
if (nums[i]== -1)return -2; //代表非法
}
if (nums[0] == 0 || nums[0] == 127) return -1; //代表跳过;
if (nums[0] >= 1 && nums[0] < 127) {
if (nums[0] == 10)return 10; //A类私有地址
else return 1;//A类
}
if (nums[0] >= 128 && nums[0] <= 191) {
if (nums[0] == 172 && nums[1] >= 16 &&
nums[1] <= 31)return 20; //B类私有地址
else return 2;//B类
}
if (nums[0] >= 192 && nums[0] <= 223) {
if (nums[0] == 192 && nums[1] == 168)return 30; //C类私有地址
else return 3;//C类
}
if (nums[0] >= 224 && nums[0] <= 239)return 4; //D类私有地址
if (nums[0] >= 240 && nums[0] <= 255)return 5; //E类私有地址
return 0;
}
bool MASKright(string& second) {
vector<int>nums(4);
nums.clear();
cut(second, nums);
// 无需判断..情况,因为空值被设置成-1了,所以一定不会相加成下面的情况。
// 全1全0
if(nums[0]+nums[1]+nums[2]+nums[3]==0||nums[0]+nums[1]+nums[2]+nums[3]==1020)return false;
//01分界在第一个数
if (uset.find(nums[0]) != uset.end() &&
nums[2] + nums[3] + nums[1] == 0)return true;
//01分界在第二个数
if (uset.find(nums[1]) != uset.end() && nums[2] + nums[3] == 0 &&
nums[0] == 255)return true;
// 01分界在第三个数
if (uset.find(nums[2]) != uset.end() && nums[3] == 0 && nums[0] == 255 &&
nums[1] == 255)return true;
// 01分界在第四个数
if (uset.find(nums[3]) != uset.end() &&
nums[0] + nums[1] + nums[2] == 765)return true;
return false;
}
int main() {
string s;
int a[7] = {0};
while (getline(cin, s)) {
int _ = s.find('~');
string second = s.substr(_ + 1, s.size() - 1);
string first = s.substr(0, _);
// 判断子网正确
bool mask = MASKright(second);
// 判断地址归属
int IP = IPwhere(first);
//子网错误且地址不跳过
if (IP!=-1&&mask == false) a[5]++;
else {
switch (IP) {
case 0:
cout << "IP出错啦" << endl;
break;
case -1:
break;
case -2:
a[5]++;
break;
case 1:
a[0]++;
break;
case 10:
a[0]++;
a[6]++;
break;
case 2:
a[1]++;
break;
case 20:
a[1]++;
a[6]++;
break;
case 3:
a[2]++;
break;
case 30:
a[2]++;
a[6]++;
break;
case 4:
a[3]++;
break;
case 5:
a[4]++;
break;
};
}
}
for (int i = 0; i < 6; i++)cout << a[i] << " ";
cout << a[6] << endl;
}
我还是没想明白为什么写for(auto num:nums)不被运行、、、
更新:找到原因了家人们,因为我错误地写了 nums.clear();
所以nums的大小被归0了,我原本以为clear函数只是清除内容,不改变大小,原来它是一点不留。
所以我原本的代码,是写错了,因为我给nums[0]-[3]是用=赋值,而不是push_back,所以数值数值赋给了一个不存在的空间,代码灵异地跑起来了。。。
哎:
clear()清空容器元素,使size()变为0,但不释放内存(capacity()通常不变)

查看30道真题和解析