华为在线编程题系列-18-识别有效的IP地址和掩码并进行分类统计

问题描述:
问题描述
问题描述

1. 问题涉及知识点.

  • 字符串处理

2. 自己解法.

  • 这个题在描述的时候说的就很不清晰
    • 子网掩码和ip地址不合格,只统计一次.
    • 255.255.255.255是不合格的子网掩码
    • 五类ip地址中包含私有地址.不对立.
  • 下面的处理就比较简单,一个条件一个条件分析.
  • 输入问题,做一个无限收入,使用arraylist收集结构.最后一起处理.
package com.chaoxiong.niuke.huawei;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * Create by tianchaoxiong on 18-4-20.
 */
public class HuaWei_18 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 收集.
        List<String> stringList =new ArrayList<String>();
        while (scanner.hasNext()){
            String string = scanner.next();
              stringList.add(string);
        }

//        int N = 4;
//        for (int i = 0; i < N; i++) {
//            String string = scanner.next();
//            stringList.add(string);
//        }
        // 处理.
        int ipA = 0;
        int ipB = 0;
        int ipC = 0;
        int ipD = 0;
        int ipE = 0;
        int errorIpMask = 0;
        int privateIp = 0;

        for (String each:stringList) {
            // 1 把ip和掩码分开.
            String []strArr = each.split("~");
            // 判断ip是否合法
            boolean isPassIP = isPassIP(strArr[0]);
            boolean isPassMask = isPassMask(strArr[1]);
//            System.out.println(isPassMask);
            if(!isPassIP||!isPassMask){
                errorIpMask++;
            }
            if(isPassIP&&isPassMask){
                // return 1:A,2:B,3:C,4:D,5:E,0:P.
                int level = getIpLevel(strArr[0]);
//                System.out.println("处理的iP "+strArr[0]);
//                System.out.println("找到的等级"+level);
                if(level==1)
                    ipA++;
                if(level==2)
                    ipB++;
                if(level==3)
                    ipC++;
                if(level==4)
                    ipD++;
                if(level==5)
                    ipE++;
                boolean isPassprivateIp = isPassprivateIp(strArr[0]);
                if(isPassprivateIp)
                    privateIp++;
            }
        }
        System.out.println(ipA+" "+ipB+" "+ipC+" "+ipD+" "+ipE+" "+errorIpMask+" "+privateIp);
    }

    private static boolean isPassprivateIp(String s) {
        String []subStr = s.split("\\.");
        int tmp = Integer.parseInt(subStr[0]);
        switch (tmp){
            case 10:
                return true;
            case 172:
                if(Integer.parseInt(subStr[1])>=16&&Integer.parseInt(subStr[1])<=31){
                    return true;
                }
            case 192:
                if(Integer.parseInt(subStr[1])==168){
                    return true;
                }
        }
        return false;
    }

    private static int getIpLevel(String s) {
//        return 1:A,2:B,3:C,4:D,5:E. 0不非法0开头或者127开头
        return calcLevel(s);
    }

    private static int calcLevel(String s) {
        String []subStr = s.split("\\.");
        int tmp = Integer.parseInt(subStr[0]);
        if(tmp>=1&&tmp<=126)
            return 1;
        else {
            if (tmp >= 128 && tmp <= 191)
                return 2;
            else {
                if (tmp >= 192 && tmp <= 223)
                    return 3;
                else {
                    if (tmp >= 224 && tmp <= 239)
                        return 4;
                    else {
                        if (tmp >= 240 && tmp <= 255)
                            return 5;
                    }
                }
            }
        }
        return 0;
    }

    private static boolean isPassMask(String s) {
//        转换成二进制,前面全是1,后面全是0.
//        转成32的一个0/1数组,统计第一次出现0之前的1的总共的1的个数是否相等.
        boolean bool = isPassIP(s);
        if(!bool)
            return false;
        String []subStr = s.split("\\.");
        int []flagArr =new int[32];
        int []flagArrValue = new int[8];
        for (int i = 0; i < 8; i++) {
            flagArrValue[i] = (int) Math.pow(2, (7 - i));
        }

        int flag = 0;
        for (String each:subStr ) {
            getFlagArr(flag,each,flagArr,flagArrValue);
            flag++;
        }
        return calcOneNum(flagArr);
    }

    private static boolean calcOneNum(int[] flagArr) {
        int startOneNum = 0;
        for(int each:flagArr){
            if (each==0)
                break;
            else startOneNum++;
        }
        int allOneNum = 0;
       for(int each:flagArr){
           if(each==1)
               allOneNum++;
       }
       return (!(allOneNum==32))&&allOneNum==startOneNum;
    }

    private static void getFlagArr(int flag, String key, int[] flagArr, int[] flagArrValue) {
        // flag = 0 表示处理的是第一字段,也就是0到7位;flag = 1 表示处理第二个字段也就是8到15;
        int intKey = Integer.parseInt(key);

        while (intKey > 0) {
            int tmp = getLowNear(intKey, flag * 8, flagArr, flagArrValue);
            intKey = intKey - tmp;
        }
    }

    private static int getLowNear(int key, int start, int[] flagArr, int[] flagArrValue) {
        for (int i = 0; i < flagArrValue.length; i++) {
            if ( key >= flagArrValue[i] ) {
                flagArr[start + i] = 1;
                return flagArrValue[i];
            }
        }
        return 0;
    }

    private static boolean isPassIP(String s) {
//        1 都要小于等于255
//        2 都要大于等于0
//        3 不能有空
        String []subStr = s.split("\\.");
        for (String each:subStr ) {
            if(each.trim().equals(""))
                return false;
            int tmp = Integer.parseInt(each);
            if(tmp<0)
                return false;
            if(tmp>255)
                return false;
        }
        return true;
    }
}

3. 优质答案.

null

4. 本题总结.

本体难点在于
1. 题目的输入处理.
2. 子网掩码的正确性判断.
3. 题意较为难以理解.

猜你喜欢

转载自blog.csdn.net/u012222078/article/details/80227475
今日推荐