华为oj 识别有效的IP地址和掩码并进行分类统计


此题,可以说挺难,但我认为不是难,是恶心,没有什么高深的算法,只是有很多细节要注意,此题分两步。

1.将字符串转换成对应的ip地址和子网掩码。

2.进行分类,判断。

当然对于ip的分类比较好分类,但是子网掩码你需要判断,是不是开头全是1之后全是0,这也比较恶心。

在上代码之前,说一下,这道题测试用例就1个,而且就是题目给出的,你直接cout<<"1 0 1 0 0 2 1"就能通过,但是我不建议这样做,自己尝试写写,折磨一下,会有进步的。

#include<iostream>
#include<string>
using namespace std;

bool IsSafe(unsigned char n)
{
	bool flag = false;

	while (n)
	{
		if (!(n & 0x80))
		{
			flag = true;
		}
		else
		{
			if (flag)
			{
				return false;
			}
		}

		n = n << 1;
	}

	return true;
}

void Calculate(int *ip, int *subnet, int &a, int &b, int &c, int &d, int &e, int &ipError, int &privateIp)
{
	int i = 0;
	bool isIpError = false;
	bool isSubNetError = false;

	for (; i < 4; i++)
	{
		if (ip[i] < 0 || ip[i] > 255)
		{
			isIpError = true;
			break;
		}
	}

	//子网掩码
	bool numFlag = false;

	for (i = 0; i < 4; i++)
	{
		if (!numFlag)
		{
			if (subnet[i] != 255)
			{
				if (IsSafe(subnet[i]))
				{
					numFlag = true;
				}
				else
				{
					isSubNetError = true;
					break;
				}
			}
			else
			{
				continue;
			}
		}
		else
		{
			if (subnet[i] != 0)
			{
				isSubNetError = true;
				break;
			}
		}
	}

	if (isIpError || isSubNetError)
	{
		ipError++;
	}
	else
	{
		//ip分类
		if (ip[0] >= 0 && ip[0] <= 126)
		{
			a++;
		}
		else if (ip[0] >= 128 && ip[0] <= 191)
		{
			b++;
		}
		else if (ip[0] >= 192 && ip[0] <= 223)
		{
			c++;
		}
		else if (ip[0] >= 224 && ip[0] <= 239)
		{
			d++;
		}
		else if (ip[0] >= 240 && ip[0] <= 255)
		{
			e++;
		}

		//私有Ip
		if (ip[0] == 10 || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || (ip[0] == 192 && ip[1] == 168))
		{
			privateIp++;
		}
	}
}

void Trans(string inStr, int *ip, int *subnet)
{
	int i = 0, j = 0;
	int tmp = 0;
	bool flag = false;

	//ip
	while (1)
	{
		while (inStr[i] != '.' && inStr[i] != '~')
		{
			tmp = tmp * 10 + inStr[i] - '0';
			flag = true;
			i++;
		}

		if (flag)
		{
			flag = false;
			ip[j] = tmp;
			tmp = 0;
		}

		if (inStr[i] == '~')
		{
			break;
		}

		i++;
		j++;
	}

	j = 0;
	tmp = 0;
	i++;

	//subnet
	while (1)
	{
		while (inStr[i] != '.' && i < inStr.size())
		{
			tmp = tmp * 10 + inStr[i] - '0';
			flag = true;
			i++;
		}

		if (flag)
		{
			flag = false;
			subnet[j] = tmp;
			tmp = 0;
		}

		if (i == inStr.size())
		{
			break;
		}

		i++;
		j++;
	}
}

int main()
{
	int ip[4], subnet[4];
	string inStr = "";
	int i = 0, j = 0;

	//初始化
	for (; i < 4; i++)
	{
		ip[i] = -1;
		subnet[i] = -1;
	}


	int A = 0, B = 0, C = 0, D = 0, E = 0, IPError = 0, PrivateIP = 0;

	while (getline(cin, inStr))
	{
		Trans(inStr, ip, subnet);
		Calculate(ip, subnet, A, B, C, D, E, IPError, PrivateIP);

		for (j = 0; j < 4; j++)
		{
			ip[j] = -1;
			subnet[j] = -1;
		}
	}

	cout << A << ' ' << B << ' ' << C << ' ' << D << ' ' << E << ' ' << IPError << ' ' << PrivateIP << endl;

	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值