1. 程式人生 > >華為線上程式設計題系列-18-識別有效的IP地址和掩碼並進行分類統計

華為線上程式設計題系列-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. 題意較為難以理解.