算法学习日记 扑克牌比较 and 子网掩码对比
问题:子网掩码格式为:255.255.255.0(11111111.11111111.11111111.00000000)
IP地址举例为:192.168.0.254(11010000.10101000.00000000.11111110)
如果两个IP地址与子网掩码按位与的结果相同,那么称这两个IP地址处于同一子网中
设计程序,判断输入的两个IP地址是否处于同一子网中,如果是,输出0,否则输出2。格式错误输出1。
两个问题都没什么难度,但是要考虑很多情况。在写程序过程中出现了很多问题
(1)细节不熟练,总是要调试很久。
(2)C++的东西总是忘记
下面分别说说两个程序中的教训
1.扑克牌比较:想的算法很复杂,总喜欢将所有的功能打包成为各种函数,不知道是好是坏…………
程序如下(C语言)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
char weight_value[14]={'3','4','5','6','7','8','9','1','J','Q','K','A','2'};
int check_array_number(char *array) //得到的是真实字符的多少
{
int i=0;
while(array[i]!='\0')
{
++i;
}
return i;
}
int Compare(char *a,char *b)
{
int i=0,j=0;
for(i=0;i<14;i++)
{
if(*a==weight_value[i])
break;
}
for(j=0;j<14;j++)
{
if(*b==weight_value[j])
break;
}
if(i>j) return 1;
else return 0;
}
int main(void)
{
char *hand_1_flag=NULL,*hand_2_flag=NULL;
int number=0; //输入序列总长度
int hand_1_space_number=0; //手牌1空格数目
int hand_2_space_number=0; //手牌2空格数目
int hand_1_number=0;//手牌1字符数目
int hand_2_number=0;//手牌2字符数目
int i=0,j=0;
char pattern[50]; //存放输入的全部字符
gets(pattern);
number=check_array_number(pattern);
for(i=0;i<number;i++)
{
if(pattern[i]=='-')
break;
}
pattern[i]='\0';
hand_1_number=i;
hand_2_number=number-i-1;
hand_1_flag=pattern;
hand_2_flag=&(pattern[i+1]);
while(j<hand_1_number)
{
if(hand_1_flag[j]==' ')
hand_1_space_number++;
j++;
}
j=0;
while(j<hand_2_number)
{
if(hand_2_flag[j]==' ')
hand_2_space_number++;
j++;
}
if(hand_1_space_number==hand_2_space_number)
{
if(hand_1_space_number==2 || hand_1_space_number==4 || hand_1_space_number==3) //这几种情况只需比较首字母大小
{
if(Compare(hand_1_flag,hand_2_flag))
puts(hand_1_flag);
else
puts(hand_2_flag);
}
else
{
if(hand_1_space_number==0)
{
if(*hand_1_flag=='j' || *hand_2_flag=='j' ||(*hand_1_flag=='J' && *(hand_1_flag+1)=='O') || (*hand_2_flag=='J' && *(hand_2_flag+1)=='O'))
{
if(*hand_1_flag=='J' && *(hand_1_flag+1)=='O')
{
puts(hand_1_flag);
}
else
{
if(*hand_2_flag=='J' && *(hand_2_flag+1)=='O')
{
puts(hand_2_flag);
}
else
{
if(*hand_1_flag=='j' && *hand_2_flag!='j')
{
puts(hand_1_flag);
}
else
{
if(*hand_2_flag=='j' && *hand_1_flag!='j')
{
puts(hand_2_flag);
}
}
}
}
}
else
{
if(Compare(hand_1_flag,hand_2_flag))
puts(hand_1_flag);
else
puts(hand_2_flag);
}
}
else
{
if(hand_1_space_number==1)
{
if(hand_1_number>8 || hand_2_number>8)
{
if(hand_1_number>8)
puts(hand_1_flag);
else
puts(hand_2_flag);
}
else
{
if(Compare(hand_1_flag,hand_2_flag))
puts(hand_1_flag);
else
puts(hand_2_flag);
}
}
}
}
}
else
{
if(hand_1_space_number==1 || hand_2_space_number==1)
{
if((*hand_1_flag=='j')||(*hand_2_flag=='j')||((*hand_1_flag=='J')&&(hand_1_number>8))||((*hand_2_flag=='J')&&(hand_2_number>8)))
printf("joker JOKER");
}
else
{
if(hand_1_space_number==3 || hand_2_space_number==3)
{
if(hand_1_space_number==3)
puts(hand_1_flag);
else
puts(hand_2_flag);
}
else
{
printf("ERROR");
}
}
}
return 0;
}
2.子网掩码对比:改用C++来写所有的程序,主要教训如下
(1)将字符串转换成int:定义一个istringstream流,绑定要转换的字符串,然后将字符串输出至指定int型变量中,完成转换
void IP_int(string code,int *code_i)
{
string code_a[4]={};
int i=0,j=0;
for(i=0;i<4;i++)
{
while(code[j]!='.' && code[j]!='\0')
{
code_a[i]+=code[j];
j++;
}
j++;
}
for(i=0;i<4;i++)
{
istringstream in(code_a[i]);
in>>code_i[i];
}
}
(2)string容器中也是以‘\0’作为字符串的结尾,因此cout时可以利用这一点。
(3)string.compare(string str)
string.empty
函数不要忘记!!
子网掩码程序如下
#include <iostream>
#include <sstream> //用istringstream要加上这个库
#include <string>
#include <cctype>
using namespace std;
int check_IP(string code)
{
string ever[4]={};
int sybol_number=0;
int number=0;
int len=code.length();
int i=0,j=0;
for(i=0;i<len;i++)
{
if(code[i]=='.')
sybol_number++;
}
if(sybol_number!=3) return 0;
else
{
for(i=0;i<=3;i++)
{
while(code[j]!='.' && code[j]!='\0')
{
ever[i]+=code[j];
j++;
}
j++;
}
for(i=0;i<=3;i++)
{
if(ever[i].empty()==1)
{
return 0;
}
else
{
istringstream is(ever[i]); //将string转成int的方法
is>>number;
if(number>255) return 0;
}
}
return 1;
}
}
int check_mask(string mask)
{
string ever[4]={};
int sybol_number=0;
string subnet_code[4]={"255","255","255","0"};
int len=mask.length();
int i=0,j=0;
for(i=0;i<len;i++)
{
if(mask[i]=='.')
sybol_number++;
}
if( sybol_number!=3) return 0;
else
{
for(i=0;i<=3;i++)
{
while(mask[j]!='.' && mask[j]!='\0')
{
ever[i]+=mask[j];
j++;
}
j++;
}
for(i=0;i<=3;i++)
{
if(ever[i].compare(subnet_code[i])!=0)
return 0;
}
return 1;
}
}
void IP_int(string code,int *code_i)
{
string code_a[4]={};
int i=0,j=0;
for(i=0;i<4;i++)
{
while(code[j]!='.' && code[j]!='\0')
{
code_a[i]+=code[j];
j++;
}
j++;
}
for(i=0;i<4;i++)
{
istringstream in(code_a[i]);
in>>code_i[i];
}
}
int checkNetSegment(string mask,string ip1,string ip2)
{
int i=0;
int c_1,c_2,c_m;
c_1=check_IP(ip1);
c_2=check_IP(ip2);
c_m=check_mask(mask);
int mask_i[4]={},ip1_i[4]={},ip2_i[4]={};
IP_int(mask,mask_i);
IP_int(ip1,ip1_i);
IP_int(ip2,ip2_i);
if( c_1 && c_2 && c_m)
{
for(i=0;i<=3;i++)
{
if((mask_i[i] & ip1_i[i])!=(mask_i[i] & ip2_i[i]))
return 2;
}
return 0;
}
else
{
return 1;
}
}
int main()
{
string ip1;
string ip2;
string mask;
cin>>mask>>ip1>>ip2;
cout<<checkNetSegment(mask,ip1,ip2)<<endl;
}