菜鸟之路Day18一一IO流综合练习

embedded/2025/3/1 16:47:06/

菜鸟之路Day18一一IO流综合练习

作者:blue

时间:2025.2.21

文章目录

  • 菜鸟之路Day18一一IO流综合练习
    • 0.概述
    • 1.生成假数据(网页爬虫)
    • 2.随机点名器
      • 2.1随机点名器1
      • 2.2随机点名器2
      • 2.3随机点名器3
      • 2.4随机点名器4
      • 2.5随机点名器5(带权重的随机算法)

0.概述

文章内容学习自黑马程序员BV1yW4y1Y7Ms

1.生成假数据(网页爬虫)

实现了一个姓名生成器,主要功能是从指定网页爬取姓氏、男孩名和女孩名数据,处理后生成随机组合的姓名,并附加性别和年龄信息,最终将结果写入文件。

代码通过爬虫、正则匹配和随机化处理,生成包含姓氏、性别和年龄的模拟数据,适用于需要批量生成测试姓名的场景。

java">package FinallyTest;import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class FinallyTest1 {public static void main(String[] args) throws IOException {//https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d//http://www.haoming8.cn/baobao/10881.html//http://www.haoming8.cn/baobao/7641.html//1.创建字符串表示网址String FamilyNameNet = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d";String BoyNameNet = "http://www.haoming8.cn/baobao/10881.html";String GirlNameNet = "http://www.haoming8.cn/baobao/7641.html";//2.爬取网页上的信息//仅仅爬取出了前端源码String FamilyNameInfo = webCrawler(FamilyNameNet);String BoyNameInfo = webCrawler(BoyNameNet);String GirlNameInfo = webCrawler(GirlNameNet);//3.获取真正想要的信息ArrayList<String> FamilyNameTempList = getData(FamilyNameInfo, "(.{4})(,|。)", 1);FamilyNameTempList.removeIf(e -> e.equals("em\">"));//去除掉造成干扰的标签ArrayList<String> BoyNameTempList = getData(BoyNameInfo, "([\\u4E00-\\u9FA5]{2})(、|。)", 1);ArrayList<String> GirlNameTempList = getData(GirlNameInfo, "(.. ){4}..", 0);//4.处理数据//FamilyNameTempList(姓氏)//处理方法:获取单个姓氏ArrayList<String> FamilyNameList = new ArrayList<>();for (String s : FamilyNameTempList) {for (int i = 0; i < s.length(); i++) {FamilyNameList.add(s.charAt(i) + "");}}//BoyNameTempList(男生名字)//处理方法:去重ArrayList<String> BoyNameList = new ArrayList<>();for (String s : BoyNameTempList) {if (!BoyNameList.contains(s)) {BoyNameList.add(s);}}//GirlNameTempList(女生名字)//处理方法:切割ArrayList<String> GirlNameList = new ArrayList<>();for (String s : GirlNameTempList) {String[] s1 = s.split(" ");for (String string : s1) {GirlNameList.add(string);}}//5.组合所有姓名//格式:姓名(唯一)-性别-年龄ArrayList<String> list = getInfos(FamilyNameList, BoyNameList, GirlNameList, 50, 70);Collections.shuffle(list);System.out.println(list);//6.将数据写到文件中//这里用BufferedWriter,主要是为了使用其中的newLine方法BufferedWriter bw = new BufferedWriter(new FileWriter("src\\FinallyTest\\name.txt"));for (String name : list) {bw.write(name);bw.newLine();}bw.close();}/** 作用:组合姓名(唯一)-性别-年龄* 参数一:姓氏集合* 参数二:男生名字集合* 参数三:女生名字集合* 参数四:男生个数* 参数五:女生个数* */private static ArrayList<String> getInfos(ArrayList<String> FamilyNameList, ArrayList<String> BoyNameList, ArrayList<String> GirlNameList, int boyCount, int girlCount) {//用set来做一个去重操作//男生姓名HashSet<String> boyhs = new HashSet<>();while (true) {if (boyhs.size() == boyCount) {break;} else {//每次打乱之后再拼接Collections.shuffle(FamilyNameList);Collections.shuffle(BoyNameList);boyhs.add(FamilyNameList.getFirst() + BoyNameList.getFirst());//取第一个拼接}}//女生姓名HashSet<String> girlhs = new HashSet<>();while (true) {if (girlhs.size() == girlCount) {break;} else {//每次打乱之后再拼接Collections.shuffle(FamilyNameList);Collections.shuffle(GirlNameList);girlhs.add(FamilyNameList.getFirst() + GirlNameList.getFirst());//取第一个拼接}}ArrayList<String> list = new ArrayList<>();//存储返回值//[18-27岁]Random rd = new Random();for (String boyName : boyhs) {int age = rd.nextInt(10)+18;list.add(boyName+"-男-"+age);}for (String girlName : girlhs) {int age = rd.nextInt(10)+18;list.add(girlName+"-女-"+age);}return list;}/** 获取真正想要的数据* 参数一:*   数据源* 参数二:*   正则表达式* 参数三:*   真正想要的数据* */private static ArrayList<String> getData(String str, String regex, int index) {ArrayList<String> list = new ArrayList<>();Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(str);while (matcher.find()) {list.add(matcher.group(index));}return list;}//爬取整个网页的信息private static String webCrawler(String familyNameNet) throws IOException {//用StringBuilder对象来获取拼接的数据StringBuilder sb = new StringBuilder();//创建url对象URL url = new URL(familyNameNet);//链接到网页URLConnection conn = url.openConnection();//获取网页中的数据,conn中有getInputStream方法可以获取字节流,但是有可能涉及到爬取中文数据//所以我们用转换流把其包装为字符流InputStreamReader isr = new InputStreamReader(conn.getInputStream());int ch;while ((ch = isr.read()) != -1) {sb.append((char) ch);}//释放资源isr.close();return sb.toString();}
}

利用hutool包中的方法来尝试实现上述功能

hutool包参考文档中的代码,与我们的源代码非常接近。

java">//请求列表页
String listContent = HttpUtil.get("https://www.oschina.net/action/ajax/get_more_news_list?newsType=&p=2");
//使用正则获取所有标题
List<String> titles = ReUtil.findAll("<span class=\"text-ellipsis\">(.*?)</span>", listContent, 1);
for (String title : titles) {//打印标题Console.log(title);
}

代码实现:

java">package FinallyTest;import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;import java.util.*;public class FinallyTest2 {public static void main(String[] args) {//1.创建字符串表示网址String FamilyNameNet = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d";String BoyNameNet = "http://www.haoming8.cn/baobao/10881.html";String GirlNameNet = "http://www.haoming8.cn/baobao/7641.html";//2.爬取网页上的信息(请求列表页)String FamilyNameInfo = HttpUtil.get(FamilyNameNet);String BoyNameInfo = HttpUtil.get(BoyNameNet);String GirlNameInfo = HttpUtil.get(GirlNameNet);//3.获取真正想要的信息(使用正则获取所有标题)List<String> FamilyNameTempList = ReUtil.findAll("(.{4})(,|。)", FamilyNameInfo, 1);FamilyNameTempList.removeIf(e -> e.equals("em\">"));//去除掉造成干扰的标签List<String> BoyNameTempList = ReUtil.findAll("([\\u4E00-\\u9FA5]{2})(、|。)", BoyNameInfo, 1);List<String> GirlNameTempList = ReUtil.findAll("(.. ){4}..", GirlNameInfo, 0);//4.处理数据//FamilyNameTempList(姓氏)//处理方法:获取单个姓氏ArrayList<String> FamilyNameList = new ArrayList<>();for (String s : FamilyNameTempList) {for (int i = 0; i < s.length(); i++) {FamilyNameList.add(s.charAt(i) + "");}}//BoyNameTempList(男生名字)//处理方法:去重ArrayList<String> BoyNameList = new ArrayList<>();for (String s : BoyNameTempList) {if (!BoyNameList.contains(s)) {BoyNameList.add(s);}}//GirlNameTempList(女生名字)//处理方法:切割ArrayList<String> GirlNameList = new ArrayList<>();for (String s : GirlNameTempList) {String[] s1 = s.split(" ");for (String string : s1) {GirlNameList.add(string);}}//5.组合所有姓名//格式:姓名(唯一)-性别-年龄ArrayList<String> list = getInfos(FamilyNameList, BoyNameList, GirlNameList, 50, 70);Collections.shuffle(list);System.out.println(list);//6.将数据写到文件中FileUtil.writeLines(list, "FinallyTest\\namesHutool.txt", "UTF-8");}/** 作用:组合姓名(唯一)-性别-年龄* 参数一:姓氏集合* 参数二:男生名字集合* 参数三:女生名字集合* 参数四:男生个数* 参数五:女生个数* */private static ArrayList<String> getInfos(ArrayList<String> FamilyNameList, ArrayList<String> BoyNameList, ArrayList<String> GirlNameList, int boyCount, int girlCount) {//用set来做一个去重操作//男生姓名HashSet<String> boyhs = new HashSet<>();while (true) {if (boyhs.size() == boyCount) {break;} else {//每次打乱之后再拼接Collections.shuffle(FamilyNameList);Collections.shuffle(BoyNameList);boyhs.add(FamilyNameList.getFirst() + BoyNameList.getFirst());//取第一个拼接}}//女生姓名HashSet<String> girlhs = new HashSet<>();while (true) {if (girlhs.size() == girlCount) {break;} else {//每次打乱之后再拼接Collections.shuffle(FamilyNameList);Collections.shuffle(GirlNameList);girlhs.add(FamilyNameList.getFirst() + GirlNameList.getFirst());//取第一个拼接}}ArrayList<String> list = new ArrayList<>();//存储返回值//[18-27岁]Random rd = new Random();for (String boyName : boyhs) {int age = rd.nextInt(10)+18;list.add(boyName+"-男-"+age);}for (String girlName : girlhs) {int age = rd.nextInt(10)+18;list.add(girlName+"-女-"+age);}return list;}}

2.随机点名器

2.1随机点名器1

需求:
有一个文件里面存储了班级同学的信息,每一个信息占一行。

​ 格式为:张三-男-23

​ 要求通过程序实现随机点名器。
运行效果:
第一次运行程序:随机同学姓名1(只显示名字)

第二次运行程序:随机同学姓名2(只显示名字)

第三次运行程序:随机同学姓名3(只显示名字)

java">public class FinallyTest4 {public static void main(String[] args) throws IOException {//1.先将文件中的数据读入到集合中ArrayList<String> list = getData("src\\FinallyTest\\name.txt");//2.打乱,根据Collections.shuffle(list);String[] arr = list.getFirst().split("-");System.out.println(arr[0]);}private static ArrayList<String> getData(String path) throws IOException {BufferedReader br = new BufferedReader(new FileReader(path));ArrayList<String> list = new ArrayList<>();String elem;while((elem=br.readLine())!=null){list.add(elem);}br.close();return list;}
}

2.2随机点名器2

需求:
一个文件里面存储了班级同学的信息,每一个学生信息占一行格式为:张三-男-23。

​ 要求通过程序实现随机点名器,

运行效果:
70%的概率随机到男生

​ 30%的概率随机到女生

​ 总共随机100万次,统计结果。

注意观察:看生成男生和女生的比例是不是接近于7:3

java">package FinallyTest;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;public class FinallyTest4 {public static void main(String[] args) throws IOException {//1.先将文件中的数据读入到集合中ArrayList<String> list = getData("src\\FinallyTest\\name.txt");//2.将男女集合进行分类ArrayList<String> BoyList = new ArrayList<>();ArrayList<String> GirlList = new ArrayList<>();for (String name : list) {String[] arr = name.split("-");if(arr[1].equals("男")){BoyList.add(name);}else {GirlList.add(name);}}//3.创建一个数组,10个数,7个1,3个0,1代表抽男生,0代表抽女生,模拟概率ArrayList<Integer> arr = new ArrayList<>();Collections.addAll(arr,1,1,1,1,1,1,1,0,0,0);//4.统计次数int BoyCount=0;int GirlCount=0;for(int i=1;i<=1000000;i++){Collections.shuffle(arr);//抽男生if(arr.getFirst()==1){Collections.shuffle(BoyList);BoyCount++;System.out.println(BoyList.getFirst());}else {//抽女生Collections.shuffle(GirlList);GirlCount++;System.out.println(GirlList.getFirst());}}System.out.println(BoyCount/1000000.0+"");//0.699904System.out.println(GirlCount/1000000.0+"");//0.300096}private static ArrayList<String> getData(String path) throws IOException {BufferedReader br = new BufferedReader(new FileReader(path));ArrayList<String> list = new ArrayList<>();String elem;while((elem=br.readLine())!=null){list.add(elem);}br.close();return list;}}

2.3随机点名器3

需求:
一个文件里面存储了班级同学的姓名,每一个姓名占一行。

要求通过程序实现随机点名器

第三次必定是张三同学
运行效果:

第一次运行程序:随机同学姓名1

第二次运行程序:随机同学姓名2

第三次运行程序:张三

思路:新建一个Count文件来记录程序运行的次数

java">package FinallyTest;import java.io.*;
import java.util.ArrayList;
import java.util.Collections;public class FinallyTest5 {public static void main(String[] args) throws IOException {//1.先将文件中的数据读入到集合中ArrayList<String> list = getData("src\\FinallyTest\\name.txt");BufferedReader br = new BufferedReader(new FileReader("src\\FinallyTest\\Count.txt"));int count = br.read()-'0';BufferedWriter bw = new BufferedWriter(new FileWriter("src\\FinallyTest\\Count.txt"));if(count==2) {System.out.println("张三");bw.write(count+1+"");}else {Collections.shuffle(list);String[] arr = list.getFirst().split("-");System.out.println(arr[0]);bw.write(count+1+"");}bw.close();br.close();}private static ArrayList<String> getData(String path) throws IOException {BufferedReader br = new BufferedReader(new FileReader(path));ArrayList<String> list = new ArrayList<>();String elem;while((elem=br.readLine())!=null){list.add(elem);}br.close();return list;}
}

2.4随机点名器4

需求:
一个文件里面存储了班级同学的姓名,每一个姓名占一行。

要求通过程序实现随机点名器。

运行效果:

被点到的学生不会再被点到

如果班级中所有的学生都点完了,需要自动的重新开启第二轮点名

细节1:假设班级有10个学生,每一轮中每一位学生只能被点到一次,程序运行10次,第一轮结束

细节2:第11次运行的时候,我们自己不需要手动操作本地文件,要求程序自动开始第二轮点名

思路:新建一个文件记录被点到学生的姓名,原先的文件点到一个删一个,这样就保证了不重复,删完了,就交替两个文件中的数据,代表新一轮开始

java">public class FinallyTest6 {public static void main(String[] args) throws IOException, InterruptedException {for(int i=0;i<=120;i++){runMain();Thread.sleep(500);//暂停0.5秒查看文件效果}}private static ArrayList<String> getData(String path) throws IOException {BufferedReader br = new BufferedReader(new FileReader(path));ArrayList<String> list = new ArrayList<>();String elem;while((elem=br.readLine())!=null){list.add(elem);}br.close();return list;}private static void runMain() throws IOException {//1.获取数据ArrayList<String> list1 = getData("src\\FinallyTest\\name.txt");ArrayList<String> list2 = getData("src\\FinallyTest\\namecopy.txt");//2.打乱,点名,点一个删一个if(list1.isEmpty()){//交替list1.addAll(list2);list2.clear();}Collections.shuffle(list1);System.out.println(list1.getFirst());list2.add(list1.getFirst());list1.removeFirst();//3.写回BufferedWriter bw1 = new BufferedWriter(new FileWriter("src\\FinallyTest\\name.txt"));BufferedWriter bw2 = new BufferedWriter(new FileWriter("src\\FinallyTest\\namecopy.txt"));for (String name : list1) {bw1.write(name);bw1.newLine();}for (String name : list2) {bw2.write(name);bw2.newLine();}bw1.close();bw2.close();}
}

2.5随机点名器5(带权重的随机算法)

需求:txt文件中事先准备好一些学生信息,每个学生的信息独占一行

要求1:每次被点到的学生,再次被点到的概率在原先的基础上降低一半。

思路:首先,我们可以先处理数据,在数据中先给每个数据都添加上权重

曾博月-男-26-1
赫依娜-女-26-1
杜茜燕-女-26-1
正美丽-男-25-1
蒋胜游-男-18-1
郈蔼雅-女-26-1
连雅宁-女-24-1
于淑弘-女-23-1
宗紫凡-女-23-1
闵红新-女-27-1
蒙玉涛-男-21-1
............

创建Student类来管理学生对象

java">package FinallyTest;public class Student {private String name;private String sex;private int age;private double weight;public Student() {}public Student(String name, String sex, int age, double weight) {this.name = name;this.sex = sex;this.age = age;this.weight = weight;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}//改写了toString方法,方便写回到文件中@Overridepublic String toString() {return name + "-" + sex + "-" + age + "-" + weight;}
}

带权重的随机过程

java">package FinallyTest;import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;public class FinallyTest7 {public static void main(String[] args) throws IOException {//1.获取数据ArrayList<String> list = getData("src\\FinallyTest\\name_weight.txt");//2.处理数据ArrayList<Student> listStu = new ArrayList<>();for (String info : list) {//切割String[] arr = info.split("-");//存入到listStu中listStu.add(new Student(arr[0], arr[1], Integer.parseInt(arr[2]), Double.parseDouble(arr[3])));}//3.计算权重总和double weight_sum = 0;for (Student student : listStu) {weight_sum = weight_sum + student.getWeight();}//4.计算每个人在总权重中的实际占比double[] listRate = new double[listStu.size()];int index = 0;for (Student student : listStu) {listRate[index] = (student.getWeight() / weight_sum);index++;}//5.计算每个人权重的占比范围for (int i = 1; i < listRate.length; i++) {listRate[i] = listRate[i - 1] + listRate[i];}//6.随机抽取double x = Math.random(); //随机一个0-1的小数//binarySearch的结果 = -插入点-1//插入点 = -binarySearch的结果-1//index1即为插入点int index1 = -Arrays.binarySearch(listRate, x) - 1;//二分查找插入点System.out.println("本轮抽取到的人为:" + listStu.get(index1).getName());//被抽取到的人//7.修改权重double weight = listStu.get(index1).getWeight()/2;listStu.get(index1).setWeight(weight);//8.将listStu中的数值写回到文件中BufferedWriter bw = new BufferedWriter(new FileWriter("src\\FinallyTest\\name_weight.txt"));for (Student student : listStu) {bw.write(student.toString());bw.newLine();//换行}bw.close();}//读取文件中的数据private static ArrayList<String> getData(String path) throws IOException {BufferedReader br = new BufferedReader(new FileReader(path));ArrayList<String> list = new ArrayList<>();String elem;while ((elem = br.readLine()) != null) {list.add(elem);}br.close();return list;}
}

http://www.ppmy.cn/embedded/169096.html

相关文章

结构型模式---享元模式

概念 享元模式是一种结构型设计模式&#xff0c;他摒弃了在每个对象中保存所有数据的方式&#xff0c;通过共享多个对象所共有的相同状态&#xff0c;让你能在有限的内存容量中载入更多对象。享元模式将原始类中的数据分为内在状态数据和外在状态数据。 内在状态&#xff1a;就…

Unreal开发中使用JNI调用语法

使用Unreal引擎做Android端的应用开发&#xff0c;不可避免的会用到第三方Java接口&#xff0c;这就涉及到了JNI调用。Unreal自己有封装一套接口来调用&#xff0c;这里做个总结&#xff0c;主要是在一些自定义的数据类型转换上。其实可以跟到引擎源码的位置具体看实现。 从上…

什么是标记 PDF(Tagged PDF)?

什么是标记 PDF&#xff08;Tagged PDF&#xff09;&#xff1f; 标记 PDF 是一种包含额外信息的 PDF 文件&#xff0c;这些信息用于定义文档的结构&#xff08;如文本流、标题、表格、段落等&#xff09;。这非常有用&#xff0c;因为它可以使内容更加可访问&#xff08;文本…

短跑怎么训练提高最快·棒球1号位

棒球运动员的短跑能力直接影响跑垒、防守和进攻效率&#xff0c;提升短跑速度需结合专项需求&#xff08;如爆发力、加速度、变向能力&#xff09;进行系统训练。以下为针对性训练方案&#xff1a; 一、专项爆发力训练&#xff08;提升起跑速度&#xff09; 抗阻冲刺 用弹力带…

Angular Superresolution with Antenna Pattern Errors论文阅读

Angular Superresolution with Antenna Pattern Errors 1. 论文的研究目标与实际问题意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法与模型2.1 天线方向图误差建模2.2 改进算法:CID + 重加权 l 1 l_1 l1​最小化2.2.1 传统CID算法局限性2.2.2 新算法核心步骤2.2.3 …

单片机死机跑飞的原因

单片机死机跑飞的原因 硬件问题一.电源问题二.时钟异常三.复位电路故障四.电磁干扰&#xff08;EMI&#xff09;五.外设负载过重六.温度影响 软件原因一.内存管理问题二.中断处理错误三.看门狗配置不当四.多任务冲突 记录一下导致单片机跑飞可能出现的原因。 硬件问题 一.电源…

属性的设置

笔记 class Student:def __init__(self, name, gender):self.name nameself.__gender gender # self.__gender 是私有的实例属性# 使用property 修改方法&#xff0c;将方法转成属性使用propertydef gender(self):return self.__gender# 将我们的gender这个属性设置为可写属…

Linux学习笔记1

root用户 进入方式 su - root 可以使用exit退回到上一个用户,或者ctrl d 可以使用sudo命令为普通用户授权 但需要为普通用户配置sudo认证 执行visudo命令会自动打开/etc/sudoers 在文件的最后添加:用户名 ALL(ALL) NOPASSWD: ALL 最后wq保存 用户和用户组 Linux可以 配置多个用…