记录一次考试的刷题结果
java实现
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Pattern;
public class mytests {
public static void main (String[] args) {
// testIp();//
// errorCode();
// brotherWord();
// primePartner();
// sudoku();
// trueFraction();
twoFour();
}
/**
* 描述
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。
详细说明:
1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1;
2.牌面210对应的权值为210, J、Q、K、A权值分别为为11、12、13、1;
3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
4.输出的算式格式为4张牌通过±/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;
5.输出算式的运算顺序从左至右,不包含括号,如1+2+34的结果为24,2 A 9 A不能变为(2+1)*(9-1)=24
6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0
数据范围:一行由4张牌组成的字符串
输入描述:
输入4张牌为字符串形式,以一个空格隔开,首尾无空格;
输出描述:
输出怎么运算得到24,如果无法得出24,则输出“NONE”表示无解,如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
示例1
输入:
A A A A
复制
输出:
NONE
复制
说明:
不能实现
示例2
输入:
4 2 K A
复制
输出:
K-A4/2
复制
说明:
A+K2-4也是一种答案,输出任意一种即可
示例3
输入:
B 5 joker 4
复制
输出:
ERROR
复制
说明:
存在joker,输出ERROR
示例4
输入:
K Q 6 K
复制
输出:
NONE
复制
说明:
按一般的计算规则来看,K+K-(Q/6)=24 或 K-((Q/6)-K)=24,但是因为这个题目的运算不许有括号,所以去掉括号后变为 K+K-Q/6=26-Q/6=14/6=2 或 K-Q/6-K=1/6-K=0-K=-13,其它情况也不能运算出24点,故不存在,输出NONE
*/
private static void twoFour() {
// 1.提示输入
System.out.println(“请输入”);
// 2.获取数据
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String nextLine = scanner.nextLine();
if (nextLine.contains(“joker”)) {
System.out.println(“ERROR”);
break;
}
LinkedList rq = new LinkedList();
String[] split = nextLine.split(" “);
for (String num : split) {
if (“j”.equalsIgnoreCase(num)) {
rq.add(11);
}else if (“q”.equalsIgnoreCase(num)) {
rq.add(12);
}else if (“k”.equalsIgnoreCase(num)) {
rq.add(13);
}else if (“a”.equalsIgnoreCase(num)) {
rq.add(1);
}else {
rq.add(Integer.valueOf(num));
}
}
boolean has=dfs(rq,0,0,”");
if (!has) {
System.out.println(“NONE”);
}
}
}
private static boolean dfs(LinkedList<Integer> rq, int rsnum,int index,String rs) {
if (rsnum==24) {
int j=0;
String currs=new String(rs);
for (Integer integer : rq) {
String valueOf = String.valueOf(integer);
if (currs.contains(valueOf)) {
currs=currs.replace(valueOf, "");
j++;
}
}
if (j==4) {
System.out.println(rs);
return true;
}
}
if (index==4) {
return false;
}
int rqrsnum=rsnum;
String rqrs=rs;
String currs=new String(rs);
for (int i = 0; i < rq.size(); i++) {
Integer num= rq.get(i);
String valueOf = String.valueOf(num);
if (currs.contains(valueOf)) {
currs=currs.replace(valueOf, "");
continue;
}
if (rsnum==0) {
rsnum=num;
rs=String.valueOf(rsnum);
if (dfs(rq,rsnum,index+1,rs)) {
return true;
}
}else {
//+
rsnum=rqrsnum+num;
rs=rqrs+"+"+num;
if (dfs(rq,rsnum,index+1,rs)) {
return true;
}
//-
rsnum=rqrsnum-num;
rs=rqrs+"-"+num;
if (dfs(rq,rsnum,index+1,rs)) {
return true;
}
//*
rsnum=rqrsnum*num;
rs=rqrs+"*"+num;
if (dfs(rq,rsnum,index+1,rs)) {
return true;
}
///
rsnum=rqrsnum/num;
rs=rqrs+"/"+num;
if (dfs(rq,rsnum,index+1,rs)) {
return true;
}
}
}
return false;
}
/**
* 描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。
请注意本题含有多组样例输入!
输入描述:
输入一个真分数,String型
输出描述:
输出分解后的string
示例1
输入:
8/11
2/4
复制
输出:
1/2+1/5+1/55+1/110
1/3+1/6
复制
说明:
第二个样例直接输出1/2也是可以的
*/
private static void trueFraction() {
// 1.提示输入
System.out.println(“请输入”);
// 2.获取数据
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String nextLine = scanner.nextLine();
if ("".equals(nextLine)) {
break;
}
String[] split = nextLine.split("/");
int a=Integer.valueOf(split[0]);
int b=Integer.valueOf(split[1]);
StringBuffer sBuffer=new StringBuffer();
while (true) {
sBuffer.append("1/");
int c=b/a+1;
a=a-b%a;
b=b*c;
sBuffer.append(c);
sBuffer.append("+");
if (a==1) {
sBuffer.append("1/");
sBuffer.append(b);
break;
}else if (a>1&&b%a==0) {
sBuffer.append("1/");
sBuffer.append(b/a);
break;
}
}
System.out.println(sBuffer.toString());
}
}
/**
* 问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
输入
输出
数据范围:输入一个 9*9 的矩阵
输入描述:
包含已知数字的9X9盘面数组[空缺位以数字0表示]
输出描述:
完整的9X9盘面数组
示例1
输入:
0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1
复制
输出:
5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1
*/
private static void sudoku() {
//1.提示输入
System.out.println("请输入");
//2.获取数据
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
int[][]sudoku=new int[9][9];
LinkedList<Pos> pos=new LinkedList<Pos>();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int nextInt = scanner.nextInt();
sudoku[i][j]=nextInt;
if (nextInt==0) {
pos.add(new Pos(i, j));
}
}
}
//3.解析数据
dfs(sudoku,pos,0);
}
}
private static boolean dfs(int[][] sudoku, LinkedList<Pos> allpos, int index) {
//4.打印结果
if (allpos.size()==index) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
return true;
}
// 获取当前位置的可填数据
Pos curpos = allpos.get(index);
List<Integer> list= findNum(sudoku,curpos);
//遍历当前位置可填数据进行处理
for (Integer integer : list) {
sudoku[curpos.x][curpos.y]=integer;
if (dfs(sudoku, allpos, index+1)) {
return true;
}
}
//如果数据没有找到,则当前位置数据回填
sudoku[curpos.x][curpos.y]=0;
return false;
}
private static List<Integer> findNum(int[][] sudoku, Pos curpos) {
//将当前横竖两行的数据放入不重复的数据中
HashSet<Integer> set = new HashSet<Integer>();
for (int i = 0; i < 9; i++) {
set.add(sudoku[curpos.x][i]);
set.add(sudoku[i][curpos.y]);
}
//定义结果判断返回
ArrayList<Integer> numList = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++) {
if (!set.contains(i)) {
numList.add(i);
}
}
return numList;
}
public static class Pos {
int x;
int y;
public Pos(int x,int y){
this.x=x;
this.y=y;
}
}
/**
* 题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
输出:
输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。
数据范围: ,输入的数据大小满足
本题有多组输入
输入描述:
输入说明
1 输入一个正偶数 n
2 输入 n 个整数
题目有多组输入
输出描述:
求得的“最佳方案”组成“素数伴侣”的对数。
示例1
输入:
4
2 5 6 13
2
3 6
复制
输出:
2
0
复制
示例2
输入:
2
3 6
复制
输出:
0
*/
static int n= 0;
static int[] nums=null;
static boolean[][] isPri=null;
static int [] girls=null;
static boolean [] used=null;
@SuppressWarnings(“resource”)
private static void primePartner() {
//1.提示输入
System.out.println(“请输入:”);
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
int nextLine = scanner.nextInt();
if ("".equals(nextLine)) {
break;
}
//接收数据
n=nextLine;
nums=new int[n];
for (int i = 0; i < n; i++) {
nums[i]=scanner.nextInt();
}
//判断数据
isPri=new boolean[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i==j) {
isPri[i][j]=false;
}else {
isPri[i][j]=isPri(nums[i]+nums[j]);
}
}
}
girls=new int[n];
int sum=0;
for (int i = 0; i < n; i++) {
used=new boolean[n];
if (findOne(i)) {
sum+=1;
}
}
System.out.println(sum/2);
}
}
private static boolean findOne(int x) {
for (int i = 0; i < n; i++) {
if (isPri[x][i]&&used[i]==false) {
used[i]= true;
if (girls[i]==0||findOne(girls[i])) {
girls[i] = x;
return true;
}
}
}
return false;
}
private static boolean isPri(int n) {
if (n==2) {
return false;
}
for (int j = 2; j <= n/2; j++) {
if (n%j==0) {
return false;
}
}
return true;
}
private static boolean isOneNO(int key) {
if (key%2==0) {
return false;
}
return true;
}
/**
*
描述
定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 str ,让你寻找 str 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
注意:字典中可能有重复单词。本题含有多组输入数据。
数据范围:,输入的字符串长度满足 ,
输入描述:
先输入单词的个数n,再输入n个单词。 再输入一个单词,为待查找的单词x 最后输入数字k
输出描述:
输出查找到x的兄弟单词的个数m 然后输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。
示例1
输入:
3 abc bca cab abc 1
复制
输出:
2
bca
复制
示例2
输入:
6 cab ad abcd cba abc bca abc 1
复制
输出:
3
bca
复制
说明:
abc的兄弟单词有cab cba bca,所以输出3
经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca
* @throws:异常描述
* @version: v1.0.0
* @author: zhaoxiaowang-phq
* @date: 2021年11月18日 下午5:32:22
*
*/
@SuppressWarnings(“resource”)
private static void brotherWord() {
//1.提示输入
System.out.println(“请输入:”);
int all=0;
int start=0;
ArrayList rs = new ArrayList();
String keyWord="";
//2.定义数据并接收
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String nextLine = scanner.nextLine();
if ("".equals(nextLine)) {
break;
}
String[] split = nextLine.split(" ");
all=Integer.valueOf(split[0]);
keyWord=split[all+1];
start=Integer.valueOf(split[all+2]);
for (int i=1;i<=all;i++) {
String cur = split[i];
if (isBrother(keyWord,cur)) {
rs.add(cur);
}
}
}
//3.数据字段排序处理
rs.sort(String::compareTo);
//3.1获取指定位置的数据
String rsStr = rs.get(start-1);
int size = rs.size();
//4.打印结果
System.out.println(size);
System.out.println(rsStr);
}
private static boolean isBrother(String keyWord, String cur) {
char[] charArray1 = keyWord.toCharArray();
char[] charArray2 = cur.toCharArray();
Arrays.sort(charArray1);
Arrays.sort(charArray2);
return new String(charArray1).equals(new String(charArray2))&&!keyWord.equals(cur);
}
/**
* 开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是”相同“的错误记录。
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准
数据范围:错误记录数量满足 ,每条记录长度满足
输入描述:
每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:
示例1
输入:
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
复制
输出:
rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2
复制
说明:
输出中的第五行记录,由于文件名长度超过了16个字符,达到了17,所以第一个字符’c’应该被忽略。
最后两条记录由于文件名和行号相同,因此被视为同一个错误记录。哪怕它们的路径是不同的。
*/
@SuppressWarnings(“resource”)
private static void errorCode() {
//1.提示输入
System.out.println(“请输入:”);
Scanner sc = new Scanner(System.in);
//2.定义数据并接收结果并处理
HashSet all = new HashSet();
//1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是”相同“的错误记录。
LRULinkHashMap<String,Integer> lruLinkHashMap =new mytests().new LRULinkHashMap<String, Integer>(8);
while (sc.hasNextLine()) {
String nextLine = sc.nextLine();
if ("".equals(nextLine)) {
break;
}
if (nextLine.contains("\")) {
int indexOf = nextLine.lastIndexOf("\");
String lastStr = nextLine.substring(indexOf+1, nextLine.length());
int length = lastStr.split(" “)[0].length();
if (length>16) {
//2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
//3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
int indexOf2 = lastStr.indexOf(” ");
lastStr=lastStr.substring(indexOf2-16,lastStr.length());
}
if (all.contains(lastStr)) {
if (lruLinkHashMap.containsKey(lastStr)) {
//4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准
lruLinkHashMap.replace(lastStr, lruLinkHashMap.get(lastStr), lruLinkHashMap.get(lastStr)+1);
}
}else {
all.add(lastStr);
lruLinkHashMap.put(lastStr, 1);
}
}
}
// rzuwnjvnuz 633 1
// atl 637 1
// rwyfvzsopsuiqjnr 647 1
// eez 648 1
// fmwafhhgeyawnool 649 1
// c 637 1
// f 633 1
// ywzqaop 631 2
Set<Entry<String, Integer>> entrySet = lruLinkHashMap.entrySet();
for (Entry key : entrySet) {
System.out.println(key.getKey()+" "+ key.getValue());
}
}
class LRULinkHashMap<K, V> extends LinkedHashMap<K, V>{
private static final long serialVersionUID = 1l;
private int capacity;
public LRULinkHashMap(int capacity) {
super(capacity, 0.75f,true);
this.capacity=capacity;
}
@Override
public boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return size()>capacity;
}
}
/**
*
*
描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0-10.255.255.255
172.16.0.0-172.31.255.255
192.168.0.0-192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
- 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
- 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例1
输入:
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19…0.~255.255.255.0
复制
输出:
1 0 1 0 0 2 1
复制
说明:
10.70.44.68255.254.255.0的子网掩码非法,19…0.255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
所以最终的结果为1 0 1 0 0 2 1
示例2
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255
复制
输出:
0 0 0 0 0 0 0
复制
说明:
类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
* @version: v1.0.0
* @author: zhaoxiaowang-phq
* @date: 2021年11月18日 上午10:44:27
*
/
@SuppressWarnings(“resource”)
private static void testIp() {
//1.提示输入
System.out.println(“请输入数据:”);
//2.Scanner扫描
Scanner sc = new Scanner(System.in);
//3.定义数组并接收行数据
ArrayList scResult = new ArrayList();
while (sc.hasNextLine()) {
String lineString=sc.nextLine();
if ("".equals(lineString)) {
break;
}
if (lineString.contains("~")&&lineString.contains(".")) {
//1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
if ((lineString.startsWith(“0”)&&lineString.contains(""))||(lineString.startsWith(“127”)&&lineString.contains("*"))) {
continue;
}else {
scResult.add(lineString);
}
}
}
if (scResult.isEmpty()) {
return;
}
//4.定义结果集
int a=0, b=0,c=0,d=0,e=0,errorIp=0,privateIp=0;
//5.循环遍历ip并解析
for (String lineStrs : scResult) {
String[] split = lineStrs.split("~");
//5.1 判断前四位的正确性
String[] lineStr = split[0].split("\.");
if (lineStr.length!=4) {
errorIp++;
continue;
}
int rs=check(lineStr[0]);
rs+=check(lineStr[1]);
rs+=check(lineStr[2]);
rs+=check(lineStr[3]);
if (rs==4) {
//A类地址1.0.0.0~126.255.255.255;
if (Integer.valueOf(lineStr[0])>=1&&Integer.valueOf(lineStr[0])<=126) {
if (isErrorMark(split[1])) {
errorIp++;
continue;
}
a++;
//私网IP10.0.0.0-10.255.255.255
if (Integer.valueOf(lineStr[0])==10) {
privateIp++;
}
continue;
}
//B类地址128.0.0.0~191.255.255.255;
if (Integer.valueOf(lineStr[0])>=128&&Integer.valueOf(lineStr[0])<=191) {
if (isErrorMark(split[1])) {
errorIp++;
continue;
}
b++;
//私网IP172.16.0.0-172.31.255.255
if (Integer.valueOf(lineStr[0])==172) {
privateIp++;
}
continue;
}
//C类地址192.0.0.0~223.255.255.255;
if (Integer.valueOf(lineStr[0])>=192&&Integer.valueOf(lineStr[0])<=223) {
if (isErrorMark(split[1])) {
errorIp++;
continue;
}
c++;
//私网IP192.168.0.0-192.168.255.255
if (Integer.valueOf(lineStr[0])==192) {
privateIp++;
}
continue;
}
//D类地址224.0.0.0~239.255.255.255;
if (Integer.valueOf(lineStr[0])>=224&&Integer.valueOf(lineStr[0])<=239) {
if (isErrorMark(split[1])) {
errorIp++;
continue;
}
d++;
}
//E类地址240.0.0.0~255.255.255.255
if (Integer.valueOf(lineStr[0])>=240&&Integer.valueOf(lineStr[0])<=255) {
if (isErrorMark(split[1])) {
errorIp++;
continue;
}
e++;
}
}else {
errorIp++;
}
}
//6.打印输出结果
System.out.println(a+" “+b+” “+c+” “+d+” “+e+” “+errorIp+” "+privateIp);
}
/**
*
* @Description: 判断子网掩码是否正确
* @param:描述1描述
* @return:返回结果描述
* @throws:异常描述
* @version: v1.0.0
* @author: zhaoxiaowang-phq
* @date: 2021年11月18日 下午2:58:15
*
*/
private static boolean isErrorMark(String lineStrs) {
//对错误的子网掩码进行统计
String[] lineStr = lineStrs.split("\\.");
if (lineStr.length!=4) {
return true;
}
StringBuffer sbBuffer = new StringBuffer();
int rs=check(lineStr[0]);
rs+=check(lineStr[1]);
rs+=check(lineStr[2]);
rs+=check(lineStr[3]);
if (rs==4) {
sbBuffer.append(Integer.toBinaryString(Integer.valueOf(lineStr[0])));
sbBuffer.append(Integer.toBinaryString(Integer.valueOf(lineStr[1])));
sbBuffer.append(Integer.toBinaryString(Integer.valueOf(lineStr[2])));
sbBuffer.append(Integer.toBinaryString(Integer.valueOf(lineStr[3])));
}else {
return true;
}
String binaryMark = sbBuffer.toString();
if (binaryMark.contains("01")||!binaryMark.contains("10")) {
//privateIp 和错误的子网掩码统计在一起
//子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
//注意二进制下全是1或者全是0均为非法
return true;
}
return false;
}
private static int check(String str ) {
Pattern pattern = Pattern.compile("[0-9]*");
if ( pattern.matcher(str).matches()&&0<=Integer.valueOf(str)
&&Integer.valueOf(str)<=255) {
return 1;
}
return 0;
}
}