#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <bitset>
using namespace std;
int isSub(string sub) {
//判断子网掩码是否正确
stringstream ss(sub);
string t;
int first_1 = 0;
int first_0 = 0;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return 0;
}
int num = stoi(t);
bitset<8> bin_n(num);
string bins = bin_n.to_string();
for (int i = 0; i < 8; i++) {
if ((!first_1 && bins[i] == '0') || (first_0 && bins[i] == '1'))
return 0;
else if (!first_1 && bins[i] == '1') {
first_1 = 1;
} else if (first_1 && !first_0 && bins[i] == '0') {
first_0 = 1;
}
}
}
if (first_0 == 0 || first_1 == 0)
return 0;
else
return 1;
}
//返回-1 表示子网掩码错误, 返回 0 表示不是A类地址, 返回1 表示是A类地址
int isNetA(string addr, string sub) {
int low[] = {1, 0, 0, 0};
int top[] = {126, 255, 255, 255};
int lowp[] = {10, 0, 0, 0};
int topp[] = {10, 255, 255, 255};
//先判断子网掩码是否正确
if (!isSub(sub))
return -1;
stringstream ss(addr);
string t;
int idx = 0;
int isPriv = 1;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return -1;
}
int num = stoi(t);
if (num < 0)
return -1;
if (num < low[idx] || num > top[idx]) {
return 0;
}
if (isPriv && (num < lowp[idx] || num > topp[idx])) {
isPriv = 0;
}
idx += 1;
}
if (isPriv)
return 2;
return 1;
}
//返回-1 表示子网掩码错误, 返回 0 表示不是B类地址, 返回1 表示是B类地址
int isNetB(string addr, string sub) {
int low[] = {128, 0, 0, 0};
int top[] = {191, 255, 255, 255};
int lowp[] = {172, 16, 0, 0};
int topp[] = {172, 31, 255, 255};
//先判断子网掩码是否正确
if (!isSub(sub))
return -1;
stringstream ss(addr);
string t;
int idx = 0;
int isPriv = 1;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return -1;
}
int num = stoi(t);
if (num < 0)
return -1;
if (num < low[idx] || num > top[idx]) {
return 0;
}
if (isPriv && (num < lowp[idx] || num > topp[idx])) {
isPriv = 0;
}
idx += 1;
}
if (isPriv)
return 2;
return 1;
}
//返回-1 表示子网掩码错误, 返回 0 表示不是C类地址, 返回1 表示是C类地址
int isNetC(string addr, string sub) {
int low[] = {192, 0, 0, 0};
int top[] = {223, 255, 255, 255};
int lowp[] = {192, 168, 0, 0};
int topp[] = {192, 168, 255, 255};
//先判断子网掩码是否正确
if (!isSub(sub))
return -1;
stringstream ss(addr);
string t;
int idx = 0;
int isPriv = 1;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return -1;
}
int num = stoi(t);
if (num < 0)
return -1;
if (num < low[idx] || num > top[idx]) {
return 0;
}
if (isPriv && (num < lowp[idx] || num > topp[idx])) {
isPriv = 0;
}
idx += 1;
}
if (isPriv)
return 2;
return 1;
}
//返回-1 表示子网掩码错误, 返回 0 表示不是D类地址, 返回1 表示是D类地址
int isNetD(string addr, string sub) {
int low[] = {224, 0, 0, 0};
int top[] = {239, 255, 255, 255};
//先判断子网掩码是否正确
if (!isSub(sub))
return -1;
stringstream ss(addr);
string t;
int idx = 0;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return -1;
}
int num = stoi(t);
if (num < 0)
return -1;
if (num < low[idx] || num > top[idx]) {
return 0;
}
idx += 1;
}
return 1;
}
//返回-1 表示子网掩码错误, 返回 0 表示不是E类地址, 返回1 表示是E类地址
int isNetE(string addr, string sub) {
int low[] = {240, 0, 0, 0};
int top[] = {255, 255, 255, 255};
//先判断子网掩码是否正确
if (!isSub(sub))
return -1;
stringstream ss(addr);
string t;
int idx = 0;
while (getline(ss, t, '.')) {
if (t.size() == 0) {
return -1;
}
int num = stoi(t);
if (num < 0)
return -1;
if (num < low[idx] || num > top[idx]) {
return 0;
}
idx += 1;
}
return 1;
}
int main() {
//
int an = 0;
int bn = 0;
int cn = 0;
int dn = 0;
int en = 0;
int errn = 0;
int pn = 0;
string str;
while (getline(cin, str)) {
stringstream ss(str);
vector<string> tokens;
string t;
while (getline(ss, t, '~')) {
if (t.size() == 0) {
continue;
}
tokens.push_back(t);
}
if(tokens[0].substr(0, tokens[0].find('.'))=="0" || tokens[0].substr(0, tokens[0].find('.'))=="127")
continue;
int resa = isNetA(tokens[0], tokens[1]);
if(resa == 2){
//cout << "resa==2 : " << tokens[0] << "~" <<tokens[1] << endl;
an ++; pn ++;
continue;
}else if(resa == 1){
//cout << "resa==1 : " << tokens[0] << "~" <<tokens[1] << endl;
an ++;
continue;
}
int resb = isNetB(tokens[0], tokens[1]);
if(resb == 2){
//cout << "resb==2 : " << tokens[0] << "~" <<tokens[1] << endl;
bn ++; pn ++;
continue;
}
else if(resb == 1){
//cout << "resb==1 : " << tokens[0] << "~" <<tokens[1] << endl;
bn ++;
continue;
}
int resc = isNetC(tokens[0], tokens[1]);
if(resc == 2){
//cout << "resc==2 : " << tokens[0] << "~" <<tokens[1] << endl;
cn ++; pn ++;
continue;
}
else if(resc == 1){
//cout << "resc==1 : " << tokens[0] << "~" <<tokens[1] << endl;
cn ++;
continue;
}
int resd = isNetD(tokens[0], tokens[1]);
if(resd == 1){
//cout << "resd==1 : " << tokens[0] << "~" <<tokens[1] << endl;
dn ++;
continue;
}
int rese = isNetE(tokens[0], tokens[1]);
if(rese == 1){
//cout << "rese==1 : " << tokens[0] << "~" <<tokens[1] << endl;
en ++;
continue;
}
//cout << "error : " << tokens[0] << "~" <<tokens[1] << endl;
errn ++;
}
cout << an << " " << bn << " " << cn << " " << dn << " " <<en << " " << errn << " " << pn;
return 0;
}
// 64 位输出请用 printf("%lld")
可以将判断每个网络地址类型的函数写成一个,然后根据传入的地址范围进行判断

京公网安备 11010502036488号