习题4-5 IP网络 UVa1590

来源:互联网 发布:淘宝商城转让 编辑:程序博客网 时间:2024/05/21 20:22
算法竞赛入门经典(第2版)第4章 函数和递归

题4-5IP网络  UVa1590

感悟。

1、阅读书中题目,从网站下载英文原题,重点在看输入输出数据与格式。

2、第一种思路,存储所有输入数据,之后进行处理,耗时占空间,果断考虑第二种思路。
3、第二种思路,读入一行,处理一行,开两个字符串,一个串存最小IP,一个串存储子网掩码。
4、需编写 十进制(字符串)转二进制(字符串) 函数。
5、需编写 二进制(字符串)转十进制(字符串) 函数。

6、此类题目应该比较简单,考虑的问题不会太多,结果比较单一。写在编码之前。

7、十进制 二进制 对照如下

177 10110001
183 10110111
178 10110010
176 10110000

8、编写一步,测试一步,省得出错了,问题四处开花。

9、将4、改写为 需编写 十进制(整数)转二进制(字符串) 函数。

10、将5、改写为 需编写 二进制(字符串)转十进制(整数) 函数。

11、提交答案,很意外WA。
有什么没注意到的地方?重读英文题目。
看不出什么名堂。上网看看,有没有相关提示,或有什么测试数据。
从http://blog.csdn.net/thudaliangrx/article/details/50700688找到对应程序,先提交AC,再
进行对拍处理。
经http://blog.csdn.net/archya/article/details/38491065提示,下载了NEERC 2005测试数据,52
组数据测试下来,全部通过,再次提交WA,哪有错误?
12、对比阅读AC程序的代码,看看能有些什么发现。
读了代码发现AC程序可以测试多组数据,是个循环,本人程序只能测试一组数据,不是循环。
The input file will contain several test cases, each of them as described below.才明白输
入数据是个循环,而不是一组测试数据就结束。
13、代码写得太长,读取整数时,写得太长,通过字符串中转,看了上面的代码才发现可以直接读取。又
长进了一步。
14、提交AC,真没想到最后的错误会是读取多组数据,读取一组数据的问题。归根结底,英文理解还有一
定问题。程序写得不够漂亮,但可以看到与写得比较简短的程序是另一种体系。等有机会再写此题时,会采用另一种体系的。

2016-11-5 15:40 AC

附上AC代码,编译环境Dev-C++4.9.9.2

#include <stdio.h>
#include <string.h>

char dstr[10];
char ostr[10];//前八位有效
char ostr2[10];
char dip[40],oip[40],mip[40];
char smallip[40];
char mask[40];
int dot[10];//标记.位置
int byte[10];
int byte2[10];
void d2o(int d){//将十进制整数转化为二进制字符串
    int len;
    int i;
    //二进制字符串前8位均设置为0
    for(i=0;i<8;i++)
        ostr[i]='0';
    //十进制整数转化为二进制字符串(8位) 5%2=1 5/2=2 2%2=0 2/2=1  1%2=1 1/2=0 101
    i=8;
    ostr[i]='\0';//字符串结束标志
    
    while(d){
        i--;
        ostr[i]=d%2+'0';
        d/=2;
    }
}

int o2d(char *str){//将二进制八位字符串转化为十进制整数
    int i;
    int d=0;
    for(i=0;i<8;i++){//将二进制八位字符串转化为十进制数
        d*=2;
        d+=str[i]-'0';
    }
    return d;
}

void finddot(char *str){
    int len;
    int i;
    int count=0;
    memset(dot,0,sizeof(dot));
    len=strlen(str);
    for(i=0;i<len;i++){
        if(str[i]=='.')
            dot[count++]=i;
    }
}

void str2byte(char *str){
    int i;
    int len;
    len=strlen(str);
    memset(byte,0,sizeof(byte));
    finddot(str);
    for(i=0;i<dot[0];i++){
        byte[0]*=10;
        byte[0]+=str[i]-'0';
    }
    for(i=dot[0]+1;i<dot[1];i++){
        byte[1]*=10;
        byte[1]+=str[i]-'0';
    }
    for(i=dot[1]+1;i<dot[2];i++){
        byte[2]*=10;
        byte[2]+=str[i]-'0';
    }
    for(i=dot[2]+1;i<len;i++){
        byte[3]*=10;
        byte[3]+=str[i]-'0';
    }
}
int main(){
    int m;
    int i;
    int j;
    int n;
    
    while(scanf("%d",&m)!=EOF){
        strcpy(smallip,"");
        strcpy(mask,"");
        n=32;
        for(i=1;i<=m;i++){
            strcpy(oip,"");
            scanf("%s",dip);
        //将十进制字符串转十进制整数
            str2byte(dip);
        //将十进制整数转二进制字符串
            for(j=0;j<4;j++){//oip当前32位二进制IP字符串
                d2o(byte[j]);
                strcat(oip,ostr);
            }
            if(i==1){
                strcpy(smallip,oip);
                for(j=0;j<32;j++)
                    mask[j]='1';
                mask[j]='\0';//字符串结束标志
            }else{//确定子网掩码,即确定mask
                for(j=0;j<n;j++){
                    if(smallip[j]!=oip[j])
                        break;
                }
                if(j<32)
                    mask[j]='0';
                n=j;
            }
        }
    
    //扫描完毕
    //设计子网掩码
        for(i=0;i<n;i++){
            mask[i]='1';
        }
        for(i=n;i<32;i++){
            mask[i]='0';
        }
        mask[i]='\0';
    
    //根据子网掩码设计最小IP
        for(i=n;i<32;i++)
            oip[i]='0';
        oip[i]='\0';
    
    
        for(i=0;i<8;i++){//byte[0]数据
            ostr[i]=oip[i];
            ostr2[i]=mask[i];
        }
        ostr[8]='\0';
        byte[0]=o2d(ostr);//最小IP  
    
        ostr2[8]='\0';
        byte2[0]=o2d(ostr2);//子网掩码
    
        for(i=8;i<16;i++){//byte[1]数据
            ostr[i%8]=oip[i];
            ostr2[i%8]=mask[i];
        }
        ostr[8]='\0';
        byte[1]=o2d(ostr);
    
        ostr2[8]='\0';
        byte2[1]=o2d(ostr2);
    
        for(i=16;i<24;i++){//byte[2]数据
            ostr[i%8]=oip[i];
            ostr2[i%8]=mask[i];
        }
        ostr[8]='\0';
        byte[2]=o2d(ostr);
    
        ostr2[8]='\0';
        byte2[2]=o2d(ostr2);
    
    
        for(i=24;i<32;i++){//byte[3]数据
            ostr[i%8]=oip[i];
            ostr2[i%8]=mask[i];
        }
        ostr[8]='\0';
        byte[3]=o2d(ostr);
    
        ostr2[8]='\0';
        byte2[3]=o2d(ostr2);
    
    //格式化字符串
        sprintf(dip,"%d.%d.%d.%d",byte[0],byte[1],byte[2],byte[3]);
        sprintf(mip,"%d.%d.%d.%d",byte2[0],byte2[1],byte2[2],byte2[3]);
        printf("%s\n%s\n",dip,mip);//十进制
    }
    
    return 0;
}


0 0
原创粉丝点击