2021-10-27

此博客主要探讨了两个编程问题:一是如何实现24点游戏的算法,给定四张扑克牌,找出能计算出24的运算组合;二是如何将真分数分解为埃及分数,即表示为一系列单位分数的和。还涉及到了数独求解、素数伴侣、兄弟单词的定义和查找,以及错误代码的记录和分类。
摘要由CSDN通过智能技术生成

记录一次考试的刷题结果

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+3
4的结果为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+K
2-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均为非法

注意:

  1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
  2. 私有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;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值