提示:文章
文章目录
前言
HJ39判断两个IP是否属于同一子网
一、 代码:
第一版代码没有对掩码网络号进行处理。一开始对非法字段的理解就是value大于255。然后执行示例,
254.255.0.0
85.122.52.249
10.57.28.117
1
2
出现错误,增加修改为掩码只能是255和0这两个,跑了下面的代码,还是有示例没有通过。
cpp
#include <stdio.h>
#include <stdlib.h>
int main() {
int a, b;
char sonNet[20] = {'\0'};
char ip1[20] = {'\0'};
char ip2[20] = {'\0'};
int arraySonNet[4] = {0};
int arrayIp1[4] = {0};
int arrayIp2[4] = {0};
while (scanf("%s", sonNet) != EOF) { // 注意 while 处理多个 case
// 64 位输出请用 printf("%lld") to
char output = 'f';
char delimiters[2] = ".";
char* p = strtok(sonNet, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
if(data > 255)
{
output = '1';
break;
}
else if(data != 255 && data != 0)
{
output = '1';
break;
}
arraySonNet[index++] = data;
p = strtok(NULL, delimiters);
}
if(scanf("%s", ip1) != EOF)
{
p = strtok(ip1, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
if(data > 255)
{
output = '1';
break;
}
arrayIp1[index++] = data;
p = strtok(NULL, delimiters);
}
}
if(scanf("%s", ip2) != EOF)
{
p = strtok(ip2, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
if(data > 255)
{
output = '1';
break;
}
arrayIp2[index++] = data;
p = strtok(NULL, delimiters);
}
}
int count = 0;
for(int i = 0; i < 4; i++)
{
if( (ip1[i] & sonNet[i]) == (ip2[i] & sonNet[i]) )
{
++count;
}
}
if(output == 'f')
{
if(count == 4)
{
output = '0';
}
else {
output = '2';
}
}
printf("%c\n", output);
}
return 0;
}
255.255.252.0
173.225.245.45
69.138.93.228
2
1
这个示例没有通过。然后我仔细看了下题目对于掩码非法的说明。其中有这句话:掩码的二进制字符串前缀为网络号,都由'1'组成;后缀为主机号,都由'0'组成。
这边涉及到掩码的网络号的问题,还需要单独处理一下逻辑。
cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool isTargetSonNet(int array[], int len)
{
int tempArray[32] = {0};
int tempArrayIndex = 0;
for(int i = 0; i < len; i++)
{
int data = array[i];
if(data > 255)
{
return false;
}
int index = ((tempArrayIndex + 1) * 8);
while(data)
{
int dat = data % 2;
tempArray[--index] = dat;
data /= 2;
}
tempArrayIndex++;
}
int count = 0;
for(int i = 0; i < 32; i++)
{
int temp = tempArray[i] - tempArray[i + 1];
if(temp == 1)
{
count++;
}
}
if(count != 1)
{
return false;
}
return true;
}
int main() {
int a, b;
char sonNet[20] = {'\0'};
char ip1[20] = {'\0'};
char ip2[20] = {'\0'};
int arraySonNet[4] = {0};
int arrayIp1[4] = {0};
int arrayIp2[4] = {0};
while (scanf("%s", sonNet) != EOF) { // 注意 while 处理多个 case
// 64 位输出请用 printf("%lld") to
char output = 'f';
char delimiters[2] = ".";
char* p = strtok(sonNet, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
// if(data > 255)
// {
// output = '1';
// break;
// }
// else if(data != 255 && data != 0)
// {
// output = '1';
// break;
// }
arraySonNet[index++] = data;
p = strtok(NULL, delimiters);
}
if(!isTargetSonNet(arraySonNet, 4))
{
output = '1';
}
if(scanf("%s", ip1) != EOF)
{
p = strtok(ip1, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
if(data > 255)
{
output = '1';
break;
}
arrayIp1[index++] = data;
p = strtok(NULL, delimiters);
}
}
if(scanf("%s", ip2) != EOF)
{
p = strtok(ip2, delimiters);
int index = 0;
while(p != NULL)
{
//printf("%s\n", p);
int data = atoi(p);
if(data > 255)
{
output = '1';
break;
}
arrayIp2[index++] = data;
p = strtok(NULL, delimiters);
}
}
int count = 0;
for(int i = 0; i < 4; i++)
{
if( (ip1[i] & sonNet[i]) == (ip2[i] & sonNet[i]) )
{
++count;
}
}
if(output == 'f')
{
if(count == 4)
{
output = '0';
}
else {
output = '2';
}
}
printf("%c\n", output);
}
return 0;
}
以为上面的版本会通过,不过下面的示例还是没有通过
cpp
1.255.255.0
187.39.235.7
219.79.189.231
1
2
增加对isTargetStr函数的逻辑处理
cpp
bool isTargetSonNet(int array[], int len)
{
int tempArray[32] = {0};
int tempArrayIndex = 0;
for(int i = 0; i < len; i++)
{
int data = array[i];
if(data > 255)
{
return false;
}
int index = ((tempArrayIndex + 1) * 8);
while(data)
{
int dat = data % 2;
tempArray[--index] = dat;
data /= 2;
}
tempArrayIndex++;
}
int count = 0;
for(int i = 0; i < 32; i++)
{
int temp = tempArray[i] - tempArray[i + 1];
if(temp != 0 && temp != 1)
{
return false;
}
if(temp == 1)
{
count++;
}
}
if(count != 1)
{
return false;
}
return true;
}
还是没有通过全部示例
255.0.0.0
193.194.202.15
232.43.7.59
2
1
修改isTargetStr函数如下
cpp
bool isTargetSonNet(int array[], int len)
{
int tempArray[32] = {0};
int tempArrayIndex = 0;
for(int i = 0; i < len; i++)
{
int data = array[i];
if(data > 255)
{
return false;
}
int index = ((tempArrayIndex + 1) * 8);
while(data)
{
int dat = data % 2;
tempArray[--index] = dat;
data /= 2;
}
tempArrayIndex++;
}
int count = 0;
for(int i = 0; i + 1 < 32; i++)
{
int temp = tempArray[i] - tempArray[i + 1];
if(temp != 0 && temp != 1)
{
return false;
}
if(temp == 1)
{
count++;
}
}
if(count != 1)
{
return false;
}
return true;
}
主要是这一行: for(int i = 0; i + 1 < 32; i++)
修改后示例报错
255.255.255.0
167.-79.164.247
158.201.137.151
1
2
将isTragetStr函数改成下述形式
cpp
bool isTargetSonNet(int array[], int len)
{
int tempArray[32] = {0};
int tempArrayIndex = 0;
for(int i = 0; i < len; i++)
{
int data = array[i];
if(data > 255 || data < 0)
{
return false;
}
int index = ((tempArrayIndex + 1) * 8);
while(data)
{
int dat = data % 2;
tempArray[--index] = dat;
data /= 2;
}
tempArrayIndex++;
}
int count = 0;
for(int i = 0; i + 1 < 32; i++)
{
int temp = tempArray[i] - tempArray[i + 1];
if(temp != 0 && temp != 1)
{
return false;
}
if(temp == 1)
{
count++;
}
}
if(count != 1)
{
return false;
}
return true;
}
试了下还是不行,我才意识到可能是因为atoi的原因。
我用的atoi函数,可以转成有符号数吗?这边要处理一下。