本题将会给出
条地址信息,确切数字未知,您需要一直读取至文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
每行输入一个
形式的 IP 地址和一个
形式的子网掩码,中间用波浪线(
)分隔。保证
要么为空,要么是一个
到
间的整数。
在一行上输出七个整数,分别代表 A 类地址数、B 类地址数、C 类地址数、D 类地址数、E 类地址数、错误 IP 或错误子网掩码数、私有 IP 数。
10.70.44.68~1.1.1.5 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
1 0 1 0 0 2 1
在这个样例中:
第一条地址信息:掩码非法;
第二条地址信息:IP 格式和掩码均合法,属于 A 类;
第三条地址信息:IP 格式和掩码均合法,属于 C 类私有地址;
第四条地址信息:IP 格式非法。
统计得到
个 A 类,
个 B 类,
个 C 类,
个 D 类,
个 E 类,
个错误条目,
个私有地址。
0.201.56.50~255.255.255.0 127.201.56.50~255.255.111.255
0 0 0 0 0 0 0
在这个样例中,两条地址信息均属于上方提示中提到的特殊 IP 地址,不需要处理,直接跳过。特别需要注意地,第二条地址的子网掩码是非法的。但是因为该条为特殊 IP 地址,此优先级更高,所以不进入统计。
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-30 更新题面。
2. 2024-12-16 更新题面。
#include <stdio.h>
int main()
{
unsigned int IP[8] = {-1};
unsigned int IPType[16] = {0};
unsigned int SubnetMask[31] = {0xffffffff};
int Statistics[7] = {0};
int ErrorFlag = 0;
int i = 0;
memset(IP,-1,sizeof(unsigned int)*8);
memset(SubnetMask,0xffffffff,sizeof(unsigned int)*31);
memset(Statistics,0,sizeof(int)*7);
for(int j=0; j<31; j++)
{
SubnetMask[j] = SubnetMask[j]<<(j+1);
}
IPType[0] = 0x01000000;
IPType[1] = 0x7effffff;
IPType[2] = 0x80000000;
IPType[3] = 0xbfffffff;
IPType[4] = 0xc0000000;
IPType[5] = 0xdfffffff;
IPType[6] = 0xe0000000;
IPType[7] = 0xf0000000;
IPType[8] = 0xf0000000;
IPType[9] = 0xffffffff;
IPType[10] = 0x0a000000;
IPType[11] = 0x0affffff;
IPType[12] = 0xac100000;
IPType[13] = 0xac1fffff;
IPType[14] = 0xc0a80000;
IPType[15] = 0xc0a8ffff;
while(scanf("%d",&IP[i])!=EOF)
{
//printf("%d ",IP[i]);
if(getchar()!='\n')
{
i++;
}
else
{
i = 0;
for(int j=0; j<8; j++)
{
if(IP[j]==-1)
{
Statistics[5]++;
ErrorFlag = 1;
break;
}
}
if(ErrorFlag == 0)
{
IP[0] = (IP[0]<<24)|(IP[1]<<16)|(IP[2]<<8)|(IP[3]<<0);
IP[4] = (IP[4]<<24)|(IP[5]<<16)|(IP[6]<<8)|(IP[7]<<0);
if(SubnetMask[31-(__builtin_popcount(IP[4]))]!=IP[4])
{
Statistics[5]++;
ErrorFlag = 1;
}
else
{
if(IP[0]>=IPType[0] && IP[0]<=IPType[1])
{
Statistics[0]++;
}
else if(IP[0]>=IPType[2] && IP[0]<=IPType[3])
{
Statistics[1]++;
}
else if(IP[0]>=IPType[4] && IP[0]<=IPType[5])
{
Statistics[2]++;
}
else if(IP[0]>=IPType[6] && IP[0]<=IPType[7])
{
Statistics[3]++;
}
else if(IP[0]>=IPType[8] && IP[0]<=IPType[9])
{
Statistics[4]++;
}
if((IP[0]>=IPType[10] && IP[0]<=IPType[11]) || (IP[0]>=IPType[12] && IP[0]<=IPType[13]) || (IP[0]>=IPType[14] && IP[0]<=IPType[15]) )
{
Statistics[6]++;
}
}
}
ErrorFlag = 0;
//printf(" ");
memset(IP,-1,sizeof(int)*8);
}
}
for(int j=0; j<6; j++)
{
printf("%d ",Statistics[j]);
}
printf("%d",Statistics[6]);
return 0;
} #include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
constexpr int A = 0,
B = 1, C = 2, D = 3, E = 4, error = 5, privated = 6, other = 7;
void split(string str, char ch, vector<string>& re)
{
re.clear();
string temp;
for (char c : str)
{
if (c != ch)
{
temp += c;
}
else
{
re.push_back(temp);
temp.clear();
}
}
re.push_back(temp);
}
struct IP
{
unsigned char add[4];
bool mask;
unsigned int data()
{
unsigned int i = (unsigned int)add[0];
i <<= 8;
i += add[1];
i <<= 8;
i += add[2];
i <<= 8;
i += add[3];
return i;
}
bool load(string s)
{
// return false means error
vector<string> sp;
split(s, '.', sp);
stringstream ss;
unsigned int i = 0;
for (string& t_str : sp)
{
if (i > 4 || t_str.empty())
{
return false;
}
else
{
long long t;
ss << t_str;
ss >> t;
ss.clear();
if (t > 255 || t < 0)
{
return false;
}
else
{
add[i] = (unsigned char)t;
}
}
i++;
}
// 判断是否能成为掩码
// 使用int保存4个uchar
i = data();
if(i == 0 || i == -1)
{
mask = false;
return true;
}
bool b = false;
for (int l = 0; l < 32; l++)
{
mask = true;
if (!(i & 1) && !b)
{
;
}
else if (!(i & 1) && b)
{
mask = false;
break;
}
else if ((i & 1) && !b)
{
b = true;
}
else if ((i & 1) && b)
{
;
}
i >>= 1;
}
return true;
}
};
using Mask = IP;
int ipClsCount(string str, bool& b)
{
// 先分析ip
vector<string> ips;
split(str, '~', ips);
IP ip;
Mask mask;
if ((!mask.load(ips[1]) | !ip.load(ips[0]) ) || !mask.mask)
{
// cout << ips[0] << '\t' << ips[1] << ' ' << mask.mask << endl;
return error;
}
// Other?
if (ip.add[0] == 0 || ip.add[0] == 127)
{
return other;
}
// Private?
if (ip.add[0] == 10)
{
b = true;
}
else if (ip.add[0] == 172)
{
if (ip.add[1] >= 16 && ip.add[1] <= 31)
{
b = true;
}
else
{
b = false;
}
}
else if (ip.add[0] == 192)
{
if (ip.add[1] == 168)
{
b = true;
}
}
// A B C D E?
if (ip.add[0] <= 126)
{
return A;
}
else if (ip.add[0] <= 191)
{
return B;
}
else if (ip.add[0] <= 223)
{
return C;
}
else if (ip.add[0] <= 239)
{
return D;
}
else
{
return E;
}
}
int main()
{
string str;
while (getline(cin, str))
{
int ipCls[8] = {0};
do
{
bool isExPrivated = false;
ipCls[ipClsCount(str, isExPrivated)]++;
if (isExPrivated)
{
ipCls[privated]++;
}
} while (getline(cin, str) && str != "");
for (int i = 0; i < 6; i++)
{
cout << ipCls[i] << ' ';
}
cout << ipCls[6];
}
return 0;
} //常规思路,一步一步拆解判断、检查
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cmath>
/*
运行时间:5ms
超过35.31%用C++提交的代码
占用内存:400KB
超过79.35%用C++提交的代码
*/
using namespace std;
// 将点分十进制的ip地址转换成 255进制的 long long 整数,用于判断ip处于哪个分类区间
long long A1 = 1 * pow(255,3), A2 = 126 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long B1 = 128 * pow(255,3), B2 = 191 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long C1 = 192 * pow(255,3), C2 = 223 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long D1 = 224 * pow(255,3), D2 = 239 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long E1 = 240 * pow(255,3), E2 = 255 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long priv1 = 10 * pow(255,3),
priv12 = 10 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255;
long long priv2 = 172 * pow(255,3) + 16 * pow(255, 2),
priv22 = 172 * pow(255,3) + 31 * pow(255,2) + 255 * pow(255,1) + 255;
long long priv3 = 192* pow(255,3) + 168 * pow(255, 2),
priv32 = 192 * pow(255,3) + 168 * pow(255,2) + 255 * pow(255,1) + 255;
//按'.'符号 分割ip 或者 mask
void fillDivideString(vector<string>& divided, string& str) {
//1. 3个点分,4个数字,所以按 . 来分割ip
char local_str[str.length()+1];
memcpy(local_str, str.c_str(), str.length()+1);
const char* del = ".";
char* tmp = strtok(local_str, del);
while(nullptr != tmp) {
if(string(tmp).length() > 0) { //tmp可能为空
divided.push_back(tmp);
}
tmp = strtok(nullptr, del);
}
return;
}
//题目意思
//如果输入的一行中,Ip或mask是错误的,那么这次的输入行归为 错误IP或错误掩码
//所以,如果掩码错误或者ip错误,两者之一就可以归入,另一个不再检查
//先检查mask或先检查ip都一样
void classifyIpMask(vector<int>& count, string& ip, string& mask) {
//先检查mask合法性,如果mask非法,那么不再检查ip,
vector<string> mask_divided;
bool isvalid = true; //mask是否合法
fillDivideString(mask_divided, mask);
if(mask_divided.size() != 4) {
count[5]++; //错误掩码 +1
}
else {
//检查掩码的二进制表示,前面是连续的1,后面全是0
bool foundZero = false; //辅助检查是否全0
bool foundOne = false; //辅助检查啥否全1
for(int i = 0; i < mask_divided.size(); i++) {
int m = stoi(mask_divided[i]);
int offset = 7; //注意每个part只有8位,所以最大偏移是 7
while(offset >= 0 && isvalid) {
if((m >> offset) & 1) { //该bit是 1
foundOne = true;
if(foundZero) {
isvalid = false;
break;
}
} else { //否则 该bit是0
if(!foundZero) {
foundZero = true;
}
}
offset--;
}
//违反:前面是连续的1,后面全是0
if(!isvalid) {
count[5]++;
break;
}
}
//违反:全1或者全0
if(isvalid && (!foundZero || !foundOne)) {
isvalid = false;
count[5]++;
}
}
//如果前面mask检查好合法,继续检查ip
if(isvalid) {
vector<string> ip_divided;
fillDivideString(ip_divided, ip);
if(ip_divided.size() != 4) { //不合法
count[5]++; //错误IP地址 +1
} else {
//ip分类
long long sum = 0;
for(int i = 0; i < ip_divided.size(); i++) {
//FIX ME: 实际上这里还需要检查 stoi 的参数是否是数字字符串
long long n = stoi(ip_divided[i]);
sum += (n * pow(255, 3-i)); //转成一个255进制的数
}
if(A1 <= sum && sum <= A2) { //A类
count[0]++;
}
else if(B1 <= sum && sum <= B2) { //B类
count[1]++;
}
else if(C1 <= sum && sum <= C2) { //C类
count[2]++;
}
else if(D1 <= sum && sum <= D2) { //D类
count[3]++;
}
else if(E1 <= sum && sum <= E2) { //E类
count[4]++;
}
if((priv1 <= sum && sum <= priv12) //私有IP
|| (priv2 <= sum && sum <= priv22)
|| (priv3 <= sum && sum <= priv32)) {
count[6]++;
}
}
}
}
int main() {
string ip_and_mask;
vector<int> count(7, 0);
while(cin >> ip_and_mask) {
int pos = ip_and_mask.find_first_of('~');
string ip = ip_and_mask.substr(0,pos);
string mask = ip_and_mask.substr(pos+1);
classifyIpMask(count, ip, mask);
}
for(int i = 0; i < count.size(); i++) {
cout << count[i];
if(i < count.size()-1) cout << " ";
}
cout << endl;
} for(int i=left;i<right;i++){//将数字拼成字符串
stemp+=str[i];
} temp=stoi(stemp); vv.push_back(temp);
if(left==right && right!=str.size()-1){//如果出现连续字符时,为错误IP或掩码
err++;
iserr=true;
break;
} void vld(vector<int> vv,bool &iserr){
int zero=0,one=32;
long long int sum=0;
if(vv[4]==0 || vv[7]==255){
err++;
iserr=true;
return ;
}//全0全1直接非法
for(int i=4;i<8;i++){
int temp=vv[i];
sum=(sum<<8)+temp;//将掩码拼在一起
}
for(int i=0;i<32;i++){
if(sum%2==1&&one==32)
one-=i+1;//最右的1
if(sum%2==0)
zero++;//0的数量
sum=sum/2;
}
if((zero+one)!=31){//如果0都在1的右边,则0和1的和为31,否则为非法掩码
err++;
iserr=true;
return ;
}
else if(vv[0]==0 || vv[0]==127){//判断是否为无效IP
iserr=true;
return;
}
return ;
} 全部代码如下,仅供参考。 #include<iostream>
#include<vector>
using namespace std;
int a=0,b=0,c=0,d=0,e=0,err=0,prv=0;
bool iserr=false;
void ip(int num){
if(num>=1 && num<=126) a++;
else if(num>=128 && num<=191) b++;
else if(num>=192 && num<=223) c++;
else if(num>=224 && num<=239) d++;
else if(num>=240 && num<=255) e++;
return;
}
void prvip(int fir,int sec){
if(fir==10) prv++;
else if(fir==172 && sec>=16 && sec<=31) prv++;
else if(fir==192 && sec==168) prv++;
return;
}
void vld(vector<int> vv,bool &iserr){
int zero=0,one=32;
long long int sum=0;
if(vv[4]==0 || vv[7]==255){
err++;
iserr=true;
return ;
}//全0全1直接非法
for(int i=4;i<8;i++){
int temp=vv[i];
sum=(sum<<8)+temp;//将掩码拼在一起
}
for(int i=0;i<32;i++){
if(sum%2==1&&one==32)
one-=i+1;//最右的1
if(sum%2==0)
zero++;//0的数量
sum=sum/2;
}
if((zero+one)!=31){//如果0都在1的右边,则0和1的和为31,否则为非法掩码
err++;
iserr=true;
return ;
}
else if(vv[0]==0 || vv[0]==127){//判断是否为无效IP
iserr=true;
return;
}
return ;
}
int main(){
int temp;
int left=0,right;//left为每个数字的头,right为每个数字的尾后一位
string str,stemp;
vector<int> vv;
while(cin>>str)
{
for(right=0;right<str.size();right++){
if(str[right]=='.' || str[right]=='~' || right==str.size()-1){//当right为字符或者为最后一位时读取数据
if(left==right && right!=str.size()-1){//如果出现连续字符时,为错误IP或掩码
err++;
iserr=true;
break;
}
if(right==str.size()-1)//当right为最后一位时,+1则为尾后一位;
right++;
for(int i=left;i<right;i++){//将数字拼成字符串
stemp+=str[i];
}
temp=stoi(stemp);
vv.push_back(temp);
stemp.clear();
left=right+1;//更新left
}
}
if(!iserr){
vld(vv,iserr);
if(!iserr){
ip(vv[0]);
prvip(vv[0],vv[1]);
}
}
str.clear();
vv.clear();
left=0;
iserr=false;
}
cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<" "<<err<<" "<<prv<<endl;
return 0;
} #include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<int> parser(string& s) {
vector<int> nums;
int i = 0, j = 0;
while(j < s.size()) {
if(s[j]!='.') {
++j;
} else {
if(i==j) {
nums.push_back(-1);
} else {
nums.push_back(atoi(s.substr(i, j-i).c_str()));
}
++j;
i = j;
}
}
if(i==j) {
nums.push_back(-1);
} else {
nums.push_back(atoi(s.substr(i, j-i).c_str()));
}
return nums;
}
bool isOk(vector<int>& nums) {
if(nums.size() != 4) return false;
for(int i=0; i<4; ++i) {
if(nums[i] < 0 || nums[i] > 255) return false;
}
return true;
}
bool isMask(vector<int>& nums) {
unsigned num = 0;
for(unsigned n : nums) {
num <<= 8;
num |= n;
}
if(num == 0) return false;
unsigned bit = (1<<31);
while(bit) {
if((num&bit) == 0) break;
bit >>= 1;
}
if(bit == 0) return false;
while(bit) {
if((num&bit) != 0) return false;
bit >>= 1;
}
return true;
}
int main() {
int A=0, B=0, C=0, D=0, E=0, F=0, G=0;
string str;
while(cin >> str) {
int i=0;
while(str[i]!='~') ++i;
string ip = str.substr(0, i);
string mask = str.substr(i+1, str.size()-i);
vector<int> nums = parser(ip);
vector<int> masks = parser(mask);
if(isOk(nums) && isOk(masks) && isMask(masks)) {
if(nums[0] != 127 && nums[0] != 0) {
if(nums[0] >= 1 && nums[0] <= 126) {
++A;
} else if(nums[0] >= 128 && nums[0] <= 191) {
++B;
} else if(nums[0] >= 192 && nums[0] <= 223) {
++C;
} else if(nums[0] >= 224 && nums[0] <= 239) {
++D;
} else if(nums[0] >= 240 && nums[0] <= 255){
++E;
}
}
if(nums[0] == 10) ++G;
if(nums[0] == 192 && nums[1] == 168) ++G;
if(nums[0] == 172 && nums[1] >=16 && nums[1] <= 31) ++G;
} else {
++F;
}
}
cout << A <<" "<< B <<" "<< C <<" "<< D <<" "
<< E <<" "<< F <<" "<< G << endl;
return 0;
} #include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
uint32_t ip_str2bit(string s) {
uint32_t tmp = 0;
int i;
i= 0;
uint32_t r = 0;
while (i < s.length()) {
if (s[i] == '.') {
r = (r << 8) + tmp;
tmp = 0;
} else {
tmp = tmp * 10 + (s[i] - '0');
}
++i;
}
r = (r << 8) + tmp;
return r;
}
void classify(string s, int r[]) {
size_t pos = s.find('~');
string s1 = s.substr(0, pos);
string s2 = s.substr(pos + 1, s.length() - pos);
uint32_t b1 = ip_str2bit(s1);
uint32_t b2 = ip_str2bit(s2);
/* classify Mask */
if (b2 == 0x00000000 || b2 == 0xFFFFFFFF) {
++r[6];
return;
}
b2 = ~b2;
if (b2 & (b2 + 1)) {
++r[6];
return;
}
/* classify IP */
// 0.*.*.* unknown network
if (!((b1 & 0xFF000000) ^ 0x00000000))
return;
// 127.*.*.* unknown network
if (!((b1 & 0xFF000000) ^ 0x7F000000))
return;
// 10.*.*.* private network
if (!((b1 & 0xFF000000) ^ 0x0A000000))
++r[7];
// 172.16.0.0 - 172.31.255.255 private network
if (!((b1 & 0xFFF00000) ^ 0xAC100000))
++r[7];
// 192.168.*.* private network
if (!((b1 & 0xFFFF0000) ^ 0xC0A80000))
++r[7];
// Type A
if (!((b1 & 0x80000000) ^ 0x00000000))
++r[1];
// Type B
if (!((b1 & 0xC0000000) ^ 0x80000000))
++r[2];
// Type C
if (!((b1 & 0xE0000000) ^ 0xC0000000))
++r[3];
// Type D
if (!((b1 & 0xF0000000) ^ 0xE0000000))
++r[4];
// Type E
if (!((b1 & 0xF0000000) ^ 0xF0000000))
++r[5];
}
int main() {
string s;
int r[8] = {0};
while (getline(cin, s)) {
classify(s, r);
}
for (int i = 1; i < 7; ++i) {
cout << r[i] << ' ';
}
cout << r[7] << endl;
return 0;
} 输入利用scanf对格式的识别
n = scanf("%d.%d.%d.%d~%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3],
&mask[0],&mask[1],&mask[2],&mask[3])) != EOF 返回值n为匹配到的整型数数量,n!=8说明读取错误,那么直接排除,不过要记得使用scanf("%s" , buf)把未读取到的字段清理一下,否则影响下次读取并死锁。当n=EOF=-1的时候,读到数据结尾,退出循环。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum IPCLASS{
A = 0, B, C, D, E,
ERR, PRI
} ipclass;
int main(){
int classcnt[7] = {0}; // ip分类计数
int n ; // 接收scanf返回值
int ip[4] = {0};
int mask[4] = {0};
while( (n = scanf("%d.%d.%d.%d~%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3],
&mask[0],&mask[1],&mask[2],&mask[3])) != EOF ){
// 1.字段不对
if( n != 8 ){
// 不是ip错了就是mask错了
ipclass = ERR;classcnt[ipclass] ++;
char buf[1024] ; scanf("%s", buf) ; //清理错误缓存
continue;
}
// 2.掩码是否为连续1与全0组合
int i = 0;
int flags = 0; // 缺0字段标志,之后字段必须全0
int mask_err = 0; // 错误标志
if( (mask[0] == 0 && mask[1] == 0 && mask[2] == 0 && mask[3] == 0) ||
(mask[0] == 255 && mask[1] == 255 && mask[2] == 255 && mask[3] == 255))
mask_err = 1;
else
for( ; i < 4 ; i ++ ){
if( flags && mask[i] > 0 ){
mask_err = 1 ; break;
}
switch( mask[i] ){
case 255 : break; // 全1全0直接进入下一位判断
case 0 : case 254: case 252: case 248: case 240: case 224: case 192: case 128 : // 连1判断
flags = 1 ; break;
default : mask_err = 1 ; break; // 其他情况
}
}
if( mask_err ){
// 掩码错误
ipclass = ERR ; classcnt[ipclass] ++ ; continue ;
}
// 3.ip判断 1)错误ip 小于0 大于255 , 2)ip分类 , 3)私有ip判断
// 1)错误ip
int ip_err = 0 ;
for(i=0;i<4;i++){
if( ip[i] > 255 || ip[i] < 0 ){
ip_err = 1 ; break ;
}
}
if ( ip_err ){
// ip 错误
ipclass = ERR ; classcnt[ipclass] ++ ; continue ;
}
// 2)ip分类
if (ip[0] >= 1 && ip[0] <= 126) { ipclass = A ; classcnt[ipclass] ++ ; }
else if (ip[0] >= 128 && ip[0] <= 191) { ipclass = B ; classcnt[ipclass] ++ ; }
else if (ip[0] >= 192 && ip[0] <= 223) { ipclass = C ; classcnt[ipclass] ++ ; }
else if (ip[0] >= 224 && ip[0] <= 239) { ipclass = D ; classcnt[ipclass] ++ ; }
else if (ip[0] >= 240 && ip[0] <= 255) { ipclass = E ; classcnt[ipclass] ++ ; }
// 私有ip
if (ip[0] == 10 || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || (ip[0] == 192 && ip[1] == 168))
{ ipclass = PRI ; classcnt[ipclass] ++ ; }
}
printf("%d %d %d %d %d %d %d\n" , classcnt[0] , classcnt[1] , classcnt[2] ,
classcnt[3] , classcnt[4] , classcnt[5] , classcnt[6]);
return 0;
}
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
using namespace std;
string dec2x(int n, int x)
{
string ans = "";
do
{
int t = n % x;
if (t >= 0 && t <= 9)
ans += t + '0';
else
ans += t - 10 + 'a';
n /= x;
} while (n != 0);
reverse(ans.begin(), ans.end());
return ans;
}
int x2dec(string s, int x)
{
int ans = 0;
for (int i = 0; i < s.length(); i++)
{
if (s[i] >= '0'&&s[i] <= '9')
ans = ans*x + s[i] - '0';
else
{
if (s[i] >= 'A'&&s[i] <= 'Z')
s[i] += 'a' - 'A';
ans = ans*x + s[i] - 'a' + 10;
}
}
return ans;
}
int s2i(string s)
{
int num=0;
if(s.length()==0)
return -1;//-1代表空字符串
for(int i=0;i<s.length();i++)
{
if(s[i]>='0'&&s[i]<='9')
num=num*10+s[i]-'0';
}
return num;
}
vector<string> s2n(string s,char c)
{
int pos=0;
int nextpos=s.find(c,pos);
vector<string> v;
while(nextpos!=-1)
{
v.push_back(s.substr(pos,nextpos-pos));
pos=nextpos+1;
nextpos=s.find(c,pos);
}
v.push_back(s.substr(pos,s.length()-pos));//最后没有字符c时必加
return v;
}
bool maskcheck(int amask[])
{
bool flag=false;
if(amask[0]==255)
{
if(amask[1]==255)
{
if(amask[2]==255)
{
if(amask[3]==254||amask[3]==252||amask[3]==248\
||amask[3]==240||amask[3]==224||amask[3]==192\
||amask[3]==128||amask[3]==0)
flag=true;
}
else
{
if(amask[2]==254||amask[2]==252||amask[2]==248\
||amask[2]==240||amask[2]==224||amask[2]==192\
||amask[2]==128||amask[2]==0)
if(amask[3]==0)
flag=true;
}
}
else
{
if(amask[1]==254||amask[1]==252||amask[1]==248\
||amask[1]==240||amask[1]==224||amask[1]==192\
||amask[1]==128||amask[1]==0)
if(amask[2]==0&&amask[3]==0)
flag=true;
}
}
else
{
if(amask[0]==254||amask[0]==252||amask[0]==248\
||amask[0]==240||amask[0]==224||amask[0]==192\
||amask[0]==128||amask[0]==0)
if(amask[1]==0&&amask[2]==0&&amask[3]==0)
flag=true;
}
return flag;
}
bool ipcheck(int aip[])
{
bool flag=false;
if(aip[0]>=0&&aip[0]<=255)
if(aip[1]>=0&&aip[1]<=255)
if(aip[2]>=0&&aip[2]<=255)
if(aip[3]>=0&&aip[3]<=255)
flag=true;
return flag;
}
int main()
{
string s;
int A=0,B=0,C=0,D=0,E=0,err=0,self=0;
while(getline(cin,s))
{
if(s=="")
break;
int pos=s.find('~');
string ip=s.substr(0,pos);
string mask=s.substr(pos+1,s.length()-pos-1);
vector<string> vip=s2n(ip,'.');
vector<string> vmask=s2n(mask,'.');
int aip[4]={0};
int amask[4]={0};
for(int i=0;i<vmask.size();i++)
{
aip[i]=s2i(vip[i]);
amask[i]=s2i(vmask[i]);
}
bool maskflag=maskcheck(amask);
bool ipflag=ipcheck(aip);
if(maskflag && ipflag)
{
if(aip[0]>=1&&aip[0]<=126)
{
A++;
if(aip[0]==10)
self++;
}
if(aip[0]>=128&&aip[0]<=191)
{
B++;
if(aip[0]==172&&aip[1]>=16&&aip[1]<=31)
self++;
}
if(aip[0]>=192&&aip[0]<=223)
{
C++;
if(aip[0]==192&&aip[1]==168)
self++;
}
if(aip[0]>=224&&aip[0]<=239)
D++;
if(aip[0]>=240&&aip[0]<=255)
E++;
}
else
err++;
}
cout<<A<<" "<<B<<" "<<C<<" "<<D<<" "<<E<<" "<<err<<" "<<self<<endl;
} #include"iostream"
#include"string"
using namespace std;
int main()
{
string str;
int Aip = 0;
int Bip = 0;
int Cip = 0;
int Dip = 0;
int Eip = 0;
int Myip = 0;
int errorip = 0;
while(cin>>str)
{
int len = str.length();
int num[8] = {0};
//for(int i=0;i<len;i++)
//int i=0;
int flag = 0;
while(1)
{
int i = 0;
int num1 = 0;
while(str[i]!='.')
{
i++;
num1++;
}
if(num1==0)
{
break;
}
for(int a=0;a<num1;a++)
{
num[0]=num[0]*10+(str[a]-'0');
}
int num2 = num1;
i++;
num2++;
while(str[i]!='.')
{
i++;
num2++;
}
if(num2==num1+1)
{
break;
}
for(int b=num1+1;b<num2;b++)
{
num[1]=num[1]*10+(str[b]-'0');
}
int num3 = num2;
i++;
num3++;
while(str[i]!='.')
{
i++;
num3++;
}
if(num3==num2+1)
{
break;
}
for(int c=num2+1;c<num3;c++)
{
num[2]=num[2]*10+(str[c]-'0');
}
int num4 = num3;
i++;
num4++;
while(str[i]!='~')
{
i++;
num4++;
}
if(num4==num3+1)
{
break;
}
for(int d=num3+1;d<num4;d++)
{
num[3]=num[3]*10+(str[d]-'0');
}
//cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<" "<<num[3];
int num5 = num4;
i++;
num5++;
while(str[i]!='.')
{
i++;
num5++;
}
if(num5==num4+1)
{
break;
}
for(int e=num4+1;e<num5;e++)
{
num[4]=num[4]*10+(str[e]-'0');
}
int num6 = num5;
i++;
num6++;
while(str[i]!='.')
{
i++;
num6++;
}
if(num6==num5+1)
{
break;
}
for(int f=num5+1;f<num6;f++)
{
num[5]=num[5]*10+(str[f]-'0');
}
int num7 = num6;
i++;
num7++;
while(str[i]!='.')
{
i++;
num7++;
}
if(num7==num6+1)
{
break;
}
for(int g=num6+1;g<num7;g++)
{
num[6]=num[6]*10+(str[g]-'0');
}
int num8 = num7;
i++;
num8++;
while(i<len)
{
i++;
num8++;
}
if(num8==num7+1)
{
break;
}
for(int h=num7+1;h<num8;h++)
{
num[7]=num[7]*10+(str[h]-'0');
}
//cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<" "<<num[3]
//<<" "<<num[4]<<" "<<num[5]<<" "<<num[6]<<" "<<num[7];
flag = 1;
break;
}
if(flag == 0)
{
errorip++;
continue;
}
unsigned int temp = 0;
for(int j=4;j<8;j++)
{
temp=num[j]+(temp<<(8));
}
temp = ~temp+1;
if((temp&(temp-1))!=0)
{
errorip++;
continue;
}
if((num[4]==0)||num[7]==255)
{
errorip++;
continue;
}
int flag2 = 0;
if((num[0]>=1)&&(num[0]<=126))
{
flag2 = 1;
Aip++;
}
else if((num[0]>=128)&&(num[0]<=191))
{
flag2 = 1;
Bip++;
}
else if((num[0]>=192)&&(num[0]<=223))
{
flag2 = 1;
Cip++;
}
else if((num[0]>=224)&&(num[0]<=239))
{
flag2 = 1;
Dip++;
}
else if((num[0]>=240)&&(num[0]<=255))
{
flag2 = 1;
Eip++;
}
if((num[0]==10)
||((num[0]==172)&&(num[1]>=16)&&(num[1]<=31))
||((num[0]==192)&&(num[1]==168)))
{
flag2 = 1;
Myip++;
}
if((num[4]==0)||(num[4]==127))
{
continue;
}
}
cout<<Aip<<" "<<Bip<<" "<<Cip<<" "<<Dip<<" "<<Eip<<" "<<errorip<<" "<<Myip;
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
//IP地址
#define A_ADDR_FROM 0x01000000
#define A_ADDR_TO 0x7EFFFFFF
#define B_ADDR_FROM 0x80000000
#define B_ADDR_TO 0xBFFFFFFF
#define C_ADDR_FROM 0xC0000000
#define C_ADDR_TO 0xDFFFFFFF
#define D_ADDR_FROM 0xE0000000
#define D_ADDR_TO 0xEFFFFFFF
#define E_ADDR_FROM 0xF0000000
#define E_ADDR_TO 0xFFFFFFFF
//私网IP地址
#define PRIVATE_IP1_FROM 0x0A000000
#define PRIVATE_IP1_TO 0x0AFFFFFF
#define PRIVATE_IP2_FROM 0xAC100000
#define PRIVATE_IP2_TO 0xAC1FFFFF
#define PRIVATE_IP3_FROM 0xC0A80000
#define PRIVATE_IP3_TO 0xC0A8FFFF
int main()
{
char ip[2000][200] = {0};
int b1,b2,b3,b4;
int m1,m2,m3,m4;
int count = 0;
while(1){
if (scanf("%s",&ip[count][0]) != EOF){
count++;
} else {
break;
}
}
int out[7]={0};
int i,ipValue;
char* tmp;
int ipFlg;
int maskFlg;
for (i=0; i<count; i++){
ipFlg = 0;
maskFlg = 0;
b1 = b2 = b3 = b4 = -1;
m1 = m2 = m3 = m4 = -1;
tmp = strtok(ip[i], "~");
sscanf(tmp,"%d.%d.%d.%d", &b1, &b2, &b3, &b4);
tmp = strtok(NULL, "~");
sscanf(tmp,"%d.%d.%d.%d", &m1, &m2, &m3, &m4);
if(b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1 || m1 == -1 || m2 == -1 || m3 == -1 || m4 == -1){
out[5]++; //IP地址格式错误
} else {
ipValue = m1<<24 | m2<<16 | m3<<8 | m4;
if (ipValue == 0xFFFFFFFF || ipValue == 0x0){
out[5]++; //非法掩码
} else if (((ipValue<<1)|ipValue)!=ipValue) {
out[5]++; //非法掩码
} else{
ipValue = b1<<24 | b2<<16 | b3<<8 | b4;
if(ipValue >= PRIVATE_IP1_FROM && ipValue <= PRIVATE_IP1_TO) {
out[6]++; //私有IP1
} else if (ipValue >= PRIVATE_IP2_FROM && ipValue <= PRIVATE_IP2_TO) {
out[6]++; //私有IP2
} else if (ipValue >= PRIVATE_IP3_FROM && ipValue <= PRIVATE_IP3_TO) {
out[6]++; //私有IP3
}
if(ipValue >= A_ADDR_FROM && ipValue <= A_ADDR_TO) {
out[0]++; // A类地址
} else if(ipValue >= B_ADDR_FROM && ipValue <= B_ADDR_TO) {
out[1]++; // B类地址
} else if(ipValue >= C_ADDR_FROM && ipValue <= C_ADDR_TO) {
out[2]++; // C类地址
} else if(ipValue >= D_ADDR_FROM && ipValue <= D_ADDR_TO) {
out[3]++; // D类地址
} else if(ipValue >= E_ADDR_FROM && ipValue <= E_ADDR_TO) {
out[4]++; // E类地址
}
}
}
}
printf("%d %d %d %d %d %d %d\n", out[0],out[1],out[2],out[3],out[4],out[5],out[6]);
return 0;
} 这题是真的挺难的。。。
总结一下思路:
1、读取一行字符串,把字符串拆分为ip地址字符串和子网掩码字符串;
2、把两个字符串都转化为int 型数组,ip[4],mask[4],比如192.168.0.0转化为{192,168,0,0},当遇到特殊的字符串比如19..0.,对应{19,-1,0,-1}
3、
bool maskIsValid(int* ip);
判断子网掩码是否正确,注意255.255.255.255是不合法的子网掩码,子网掩码转化为32位unsigned int Mask,对Mask取反加一,Mask=~Mask +1;Mask二进制中1的个数是1说明是正确的子网掩码
4、若子网掩码正确,判断Ip地址是否正确;
5、ip地址正确再判断IP地址属于那种类别
// recognize_ip.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
using namespace std;
int stringToint(const string& s)
{
if (s.empty() == true) return -1;
int res = 0;
for (int i = 0; i < s.size(); ++i)
{
int cur = s[i] - '0';
res = res * 10 + cur;
}
return res;
}
//s1为IP地址类型的字符串
void ipstring_to_arr(int* ip,string& s1)
{
int start = 0, end = 0;
for (int count = 0; end < s1.size(); ++end)
{
if (s1[end] == '.')
{
if (count == 2) break;
string str = s1.substr(start, end - start);
ip[count++] = stringToint(str);
start = end + 1;
}
}
string str = s1.substr(start, end - start);
ip[2] = stringToint(str);
if (end == s1.size())
str = "";
else
str = s1.substr(end + 1);
ip[3] = stringToint(str);
/*for (int i=0;i<4 ;++i)
cout << ip[i] << " ";*/
}
bool maskIsValid(int* ip)
{
if (ip[0] == 255 && ip[1] == 255 && ip[2] == 255 && ip[3] == 255)
return false;
unsigned int Mask = 0;
for (int i = 0; i < 4; ++i)
{
int cur = ip[i];
if (cur 255)
return false;
Mask = (Mask << 8) + cur;
}
Mask = ~Mask + 1;//按位取反再加1,正确的子网掩码只剩一个1
if ((Mask & (Mask - 1)) == 0)
return true;
else
return false;
}
int main()
{
int result[7] = {0,0,0,0,0,0,0};
//int T = 4;
string s;
//cin >> s;
while (cin >> s)
{
string s1, s2;
int index = 0;
bool flag = true;
for (; index < s.size(); ++index)
{
if (s[index] == '~')
break;
}
s1 = s.substr(0, index);
s2 = s.substr(index + 1);
int ip[4] = { 0 };
int mask[4] = { 0 };
ipstring_to_arr(ip, s1);
ipstring_to_arr(mask, s2);
/*cout << endl << "mask:" << endl;
for (int i : mask)
cout << i << " ";
cout << endl;*/
bool flag_mask = maskIsValid(mask);
if (flag_mask == false)
++result[5];
//判断ip的子网类型
else
{
for (int i = 0; i < 4; ++i)
{
if (ip[i] 255)
{
++result[5];//错误IP地址
flag = false;
break;
}
}
if (flag == true)
{
if (ip[0] >= 1 && ip[0] <= 126)
{
++result[0];//A类地址
if (ip[0] == 10)
++result[6];//私有ip
}
else if (ip[0] >= 128 && ip[0] <= 191)
{
if (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31)
++result[6];//私有地址
++result[1];//B类地址
}
else if (ip[0] >= 192 && ip[0] <= 223)
{
if (ip[0] == 192 && ip[1] == 168)
++result[6];//私有地址
++result[2];//C类地址
}
else if (ip[0] >= 224 && ip[0] <= 239)
++result[3];//D类地址
else if (ip[0] >= 240 && ip[0] <= 255)
++result[4];//E类地址
//else
//++result[5];//错误IP地址
}
}
}
//std::cout << "输出结果:" << endl;
cout<<result[0]<<" "<<result[1]<<" "<<result[2]<<" "<<result[3]<<" "<<result[4]<<" "
<<result[5]<<" "<<result[6]<<endl;
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[100];
int result[7] = {0};
while(~scanf("%s", str))
{
int d1, d2, d3, d4, d11, d22, d33, d44, bin[32] = {0};
memset(bin, 0, 32);
if(sscanf(str, "%d.%d.%d.%d~%d.%d.%d.%d", &d11, &d22, &d33, &d44, &d1, &d2, &d3, &d4) == 8)
{
if(d1 >= 0 && d1 <= 255 && d2 >= 0 && d2 <= 255 && d3 >= 0 && d3 <= 255 && d4 >= 0 && d4 <= 255)
{
if(d1 == d2 && d2 == d3 && d3 == d4 && (d1 == 0 || d1 == 255))
{
//putchar('a');
result[5]++;
continue;
}
else
{
int i = 7;
while(d1)
{
bin[i] = d1 % 2;
i--;
d1 /= 2;
}
i = 15;
while(d2)
{
bin[i] = d2 % 2;
i--;
d2 /= 2;
}
i = 23;
while(d3)
{
bin[i] = d3 % 2;
i--;
d3 /= 2;
}
i = 31;
while(d4)
{
bin[i] = d4 % 2;
i--;
d4 /= 2;
}
int loc0, loc1;
for(i = 0; i < 32; i++)
if(bin[i] == 0)
{
loc0 = i;
break;
}
for(i = 31; i >= 0; i--)
if(bin[i] == 1)
{
loc1 = i;
break;
}
/********************************************
for(int x = 0; x < 32; x++)
printf("%d ", bin[x]);
putchar(10);
printf("loc0 = %d, loc1 = %d\n", loc0, loc1);
********************************************/
if(loc0 < loc1)
{
//putchar('b');
result[5]++;
continue;
}
else//mask is legal
{
if(d11 >= 0 && d11 <= 255 && d22 >= 0 && d22 <= 255 && d33 >= 0 && d33 <= 255 && d44 >= 0 && d44 <= 255)
{
if(d11 == 0 || d11 == 127)
continue;
if(d11 >= 1 && d11 <= 126)
result[0]++;
else if(d11 >= 128 && d11 <= 191)
result[1]++;
else if(d11 >= 192 && d11 <= 223)
result[2]++;
else if(d11 >= 224 && d11 <= 239)
result[3]++;
else if(d11 >= 240 && d11 <= 255)
result[4]++;
else
{
//putchar('c');
result[5]++;
continue;
}
if(d11 == 10)
result[6]++;
if(d11 == 172 && d22 >= 16 && d22 <= 31)
result[6]++;
if(d11 == 192 && d22 == 168)
result[6]++;
}
else
{
//putchar('d');
result[5]++;
continue;
}
}
}
}
else
{
//putchar('f');
result[5]++;
continue;
}
}
else
{
//putchar('g');
result[5]++;
continue;
}
}
for(int j = 0; j < 7; j++)
{
if(j == 0)
printf("%d", result[j]);
else
printf(" %d", result[j]);
}
putchar(10);
return 0;
} 注释的全是debug的时候加的,人都傻了#include <iostream>
#include <vector>
#include <stack>
using namespace std;
/*
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
1. 类似于【0.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
2. 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例1
输入
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出
1 0 1 0 0 2 1
*/
//将十进制数转换为2进制数string
string intto2(long val) {
if (val == 0) {
return "00000000";
}
string str = "";
int i = 0;
while (val != 1) {
char c = (val % 2 == 0 ? '0' : '1');
str.insert(str.begin(), c);
val /= 2;
}
str.insert(str.begin(), '1');
int n = 8 - str.length() % 8;
if (n < 8) {
for (int i = 1; i <= n; i++) {
str.insert(str.begin(), '0');
}
}
return str;
}
//将二进制的string转换为10进制数
long binto10(string str) {
long val = 0;
for (int i = 0; i < str.length(); i++) {
if (str[i] == '1') {
long v = 1;
for (int j = 1; j <= str.length() - i - 1; j++) {
v *= 2;
}
val += v;
}
}
return val;
}
//将ip地址转换为2进制数string
long ipto10(string ip_str) {
vector < int > v_ip;
int index = ip_str.find_first_of('.');
while (index != -1) {
string part = ip_str.substr(0, index);
if (!part.empty()) {
v_ip.push_back(stoi(part));
}
ip_str = ip_str.substr(index + 1);
index = ip_str.find_first_of('.');
}
if (!ip_str.empty()) {
v_ip.push_back(stoi(ip_str));
}
if (v_ip.size() != 4) {
return -1;
} else {
string s = "";
vector < int > ::iterator it;
for (it = v_ip.begin(); it != v_ip.end(); it++) {
s += intto2( * it);
}
return binto10(s);
}
}
//
bool check_mask(string mask) {
vector < int > v_ip;
int index = mask.find_first_of('.');
while (index != -1) {
string part = mask.substr(0, index);
v_ip.push_back(stoi(part));
mask = mask.substr(index + 1);
index = mask.find_first_of('.');
}
v_ip.push_back(stoi(mask));
if (v_ip.size() != 4) {
return false;
} else {
string binstr = "";
vector < int > ::iterator it;
for (it = v_ip.begin(); it != v_ip.end(); it++) {
binstr += intto2( * it);
}
int index = binstr.find_first_of('0');
string tail = binstr.substr(index + 1);
if (tail.find('1') != -1) {
return false;
} else {
return true;
}
}
}
const long A[] = {
ipto10("1.0.0.0"),
ipto10("126.255.255.255")
};
const long B[] = {
ipto10("128.0.0.0"),
ipto10("191.255.255.255")
};
const long C[] = {
ipto10("192.0.0.0"),
ipto10("223.255.255.255")
};
const long D[] = {
ipto10("224.0.0.0"),
ipto10("239.255.255.255")
};
const long E[] = {
ipto10("240.0.0.0"),
ipto10("255.255.255.255")
};
const long pri1[] = {
ipto10("10.0.0.0"),
ipto10("10.255.255.255")
};
const long pri2[] = {
ipto10("172.16.0.0"),
ipto10("172.31.255.255")
};
const long pri3[] = {
ipto10("192.168.0.0"),
ipto10("192.168.255.255")
};
// C++11
int main() {
string str = "";
vector < string > vs;
while (getline(cin, str)) {
vs.push_back(str);
}
int nA = 0, nB = 0, nC = 0, nD = 0, nE = 0, nPri = 0, err = 0;
for (int i = 0; i < vs.size(); i++) {
str = vs[i];
int index = str.find_first_of('~');
string ipstr = str.substr(0, index);
string maskstr = str.substr(index + 1);
if (!check_mask(maskstr)) {
err++;
continue;
}
long ip = ipto10(ipstr);
if (ip == -1) {
err++;
} else {
if (A[0] < ip && ip < A[1]) {
nA++;
} else if (B[0] < ip && ip < B[1]) {
nB++;
} else if (C[0] < ip && ip < C[1]) {
nC++;
} else if (D[0] < ip && ip < D[1]) {
nD++;
} else if (E[0] < ip && ip < E[1]) {
nE++;
}
if ((pri1[0] < ip && ip < pri1[1]) || (pri2[0] < ip && ip < pri2[1]) || (pri3[0] < ip && ip < pri3[1])) {
nPri++;
}
}
}
cout << nA << ' ' << nB << ' ' << nC << ' ' << nD << ' ' << nE << ' ' << err << ' ' << nPri << endl;
return 0;
} //1 255.255.255.255,0.0.0.0 为非法子网掩码
//2 ip地址是不用考虑大于255的情况,以及127.x.x.x,0.0.0.0 这些忽视数据而不是算错
//2 当子网掩码错误时,不在判断ip是否有效,错误直接加一, 进行下次循环
//3 当一个ip属于ABCDE类中的一个时候,也属于私有ip时,私有ip和他属于的分类都应该加一
#include <stdio.h>
(737)#include <stdlib.h>
#include <string.h>
int IsMask(char *str)
{
int i = 0,mask=0,n,temp;
temp = atoi(str+i); //提取掩码的第一部分,保存在高24位
mask |= (temp<<24);
while(str[i++]!='.');
temp = atoi(str + i); //提取掩码的第二部分,保存在高16位
mask |= (temp<<16);
while(str[i++]!='.');
temp = atoi(str + i); //提取掩码的第三部分,保存在高8位
mask |= (temp<<8);
while(str[i++]!='.'); //提取掩码的第四部分, 保存在低8位
temp = atoi(str + i);
mask |= (temp<<0);
if(mask == 0xffffffff || mask == 0) //如果掩码全为0,或者全为1,返回0 ,标示非法
return 0;
for(i=31; i>1; i--) //从最高位开始找,若发现有01这种情况即可判定非法
{
if(((mask >> i) & 0x1) ==0 && ((mask>>(i-1)) & 0x1) ==1)
return 0;
}
return 1;
}
int main()
{
int i,n,cnt,num[4];
char temp[32]={0}; //每次输入的数据,放在temp数组临时保存
int class[7]={0}; //用于统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数
while(scanf("%s",temp) != EOF)
{
if(!IsMask(strchr(temp,'~')+1)) //如果掩码错误,直接错误+1,进行下次的判断
{
class[5]++;
continue;
}
for(i=0,cnt=0; temp[i] != '~';i++) //循环查找
{
n = atoi(temp+i);
if(n == 0 && temp[i] == '0' && cnt == 0) //ip为0.x.x.x的直接忽略
break;
if(n == 0 && temp[i] == '.') //ip为.x..x等情况说明输入错误
{
class[5]++;
break;
}
num[cnt++] = n;
if(cnt == 4) //当提取到了ip的4部分数据才判断是哪一类
{
if(num[0] >= 1 && num[0] <= 126 ) //A类地址
{
class[0]++;
if(num[0] == 10 ) //私网IP
class[6]++;
}
else if(num[0] >= 128 && num[0] <= 191) //B类地址
{
class[1]++;
if(num[0] == 172 && num[1] >= 16 && num[1] <= 31)//私网IP
class[6]++;
}
else if(num[0] >= 192 && num[0] <= 223) //C类地址
{
class[2]++;
if(num[0] == 192 && num[1] == 168 ) //私网IP
class[6]++;
}
else if(num[0] >= 224 && num[0] <= 239) //D类地址
class[3]++;
else if(num[0] >= 240 && num[0] <= 255) //E类地址
class[4]++;
}
while(temp[i] != '.' && temp[i] != '~') //寻找到下一个'.'
i++;
if(temp[i] == '~') break; //若发现'~',说名已经处理完
}
}
for(i=0;i<7;i++) //输出显示,注意输出的最后一位不能有空格
if(i<6)
printf("%d ",class[i]);
else
printf("%d",class[i]);
return 0;
} 这里的思路是一边读入一边统计,每次换行都处理一次,附加代码以便参考
#include
(849)#include
#include
(849)#define ADDR_A_START 0x01000000
#define ADDR_A_END 0X7EFFFFFF
(1210)#define ADDR_B_START 0x80000000
#define ADDR_B_END 0XBFFFFFFF
(1211)#define ADDR_C_START 0xC0000000
#define ADDR_C_END 0XDFFFFFFF
(1212)#define ADDR_D_START 0XE0000000
#define ADDR_D_END 0XEFFFFFFF
(1213)#define ADDR_E_START 0XF0000000
#define ADDR_E_END 0XFFFFFFFF
(1214)#define ADDR_S_START_1 0X0A000000
#define ADDR_S_END_1 0X0AFFFFFF
(1215)#define ADDR_S_START_2 0XAC100000
#define ADDR_S_END_2 0XAC1FFFFF
(1216)#define ADDR_S_START_3 0XC0A80000
#define ADDR_S_END_3 0XC0A8FFFF
unsigned int getHex(unsigned int ip[8],int isIp){
unsigned int result=0;
if(isIp){
for(int i=0;i<4;i++){
result<<=8;
result+=ip[i];
}
}else{
for(int i=4;i<8;i++){
result<<=8;
result+=ip[i];
}
}
return result;
}
bool checkMark(unsigned int code){
int counterR=0;
while (!(code&0x01))//找到第一个1的位置
{
code>>=1;
counterR++;
}
if(counterR==0) return false;
counterR=32-counterR;
while(counterR--)
{
code>>=1;
if(!(code&0x01)){
break;
}
}
if(counterR!=0){
return false;
}
else{
return true;
}
}
int main(){
int ips[1000][8]={0};
char in=0,lastIn=0;
int counter=0,position=0,num=0;
int wrongSign=0;
int A=0,B=0,C=0,D=0,E=0,W=0,S=0;
unsigned int markCode=0,tempIP=0;
while((in=getchar())!=EOF){
if('.'==in||'~'==in){//一个数字输入完毕
if(lastIn>'9'||lastIn<'0'){
wrongSign=1;
}
ips[counter][position]=num;
position++;
num=0;
lastIn=in;
}else if('\n'==in){//一行输入完毕
ips[counter][position]=num;
if(lastIn>'9'||lastIn<'0'){
wrongSign=1;
}
markCode=getHex(ips[counter],0);
unsigned int temp1=markCode;
//检查掩码
if(!checkMark(markCode)) {
wrongSign=1;
}
if(wrongSign){
memset(ips[counter],0,4*sizeof(unsigned int));
W++;
wrongSign=0;
}
else{
// printf("Mask->%d.%d.%d.%d\n",ips[counter][4],ips[counter][5],ips[counter][6],ips[counter][7]);
//分析地址
tempIP=getHex(ips[counter],1);
if(tempIP>=ADDR_A_START&&tempIP<=ADDR_A_END)
A++;
if(tempIP>=ADDR_B_START&&tempIP<=ADDR_B_END)
B++;
if(tempIP>=ADDR_C_START&&tempIP<=ADDR_C_END)
C++;
if(tempIP>=ADDR_D_START&&tempIP<=ADDR_D_END)
D++;
if(tempIP>=ADDR_E_START&&tempIP<=ADDR_E_END)
E++;
if(tempIP>=ADDR_S_START_1&&tempIP<=ADDR_S_END_1)
S++;
if(tempIP>=ADDR_S_START_2&&tempIP<=ADDR_S_END_2)
S++;
if(tempIP>=ADDR_S_START_3&&tempIP<=ADDR_S_END_3)
S++;
//end
counter++;
}
num=0;
position=0;
lastIn=in;
continue;
}
else{
num=num*10+(in-'0');
lastIn=in;
}
}
/* for(int i=0;i<counter;i++){
printf("Valid:%d.%d.%d.%d~%d.%d.%d.%d\n",ips[i][0],ips[i][1],ips[i][2],ips[i][3],ips[i][4],ips[i][5],ips[i][6],ips[i][7]);
} */
//开始处理地址
printf("%d %d %d %d %d %d %d\n",A,B,C,D,E,W,S);
return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
int ip_num[8],result[7]={},mask_bin[32],flag1,flag2,flag3,i,j,k,cnt_0,cnt_1;
while(scanf("%d.%d.%d.%d~%d.%d.%d.%d", &ip_num[0], &ip_num[1], &ip_num[2], &ip_num[3], &ip_num[4], &ip_num[5], &ip_num[6], &ip_num[7]) != EOF)
{
flag1 = 0;
flag2 = 0;
flag3 = 0;
cnt_0 = 0;
cnt_1 = 0;
j = 0;
for (i = 0; i < 8; i++)
{
if (ip_num[i] < 0 || ip_num[i] > 255)
{
result[5]++;
flag1 = 1;
break;
}
}
if(flag1 == 0)
{
for (i = 4; i < 8;i++)
{
k = 128;
if(ip_num[i] == 0)
{
cnt_0++;
}
else if(ip_num[i] == 255)
{
cnt_1++;
}
//写的十进制转二进制方法,可模块化
while(j<=(8*(i-3)-1))
{
if(ip_num[i] / k)
{
mask_bin[j] = 1;
ip_num[i] = ip_num[i] - k;
}
else
{
mask_bin[j] = 0;
}
k /= 2;
j++;
}
}
if(cnt_0 == 4 || cnt_1 == 4)
{
result[5]++;
flag2 = 1;
}
if(flag2==0)
{
for (i = 0; i < 31;i++)
{
if(mask_bin[i+1]>mask_bin[i])
{
result[5]++;
flag3 = 1;
break;
}
}
}
}
if(flag1 == 0 && flag2 == 0 && flag3 == 0)
{
if(ip_num[0]>=1&&ip_num[0]<=126)
result[0]++;
else if(ip_num[0]>=128&&ip_num[0]<=191)
result[1]++;
else if(ip_num[0]>=192&&ip_num[0]<=223)
result[2]++;
else if(ip_num[0]>=224&&ip_num[0]<=239)
result[3]++;
else if(ip_num[0]>=240&&ip_num[0]<=255)
result[4]++;
if(ip_num[0]==10 || (ip_num[0]==172&&ip_num[1]>=16&&ip_num[1]<=31) || (ip_num[0]==192 && ip_num[1]==168))
{
result[6]++;
}
}
}
printf("%d %d %d %d %d %d %d", result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
return 0;
}