Java随机点名器(带权重的随机算法)
通过带权重的随机算法来实现随机点名器,该点名器的效果是点到的学生再次被点到的概率下降一半。
核心思想:给每个学生设置权重,初始权重全部为1.0,计算权重总和和学生实际的占比,然后在创建数组来模拟权重范围,例如:
arr = {1.0,2.0,3.0,4.0,5.0,6.0},那么如果随机数随机到3.14,则表示点到的学生位于3.0-4.0之间,在返回数组中3.14这个数应存入位置的索引来表示是第几个学生被点到了。
第一个同学范围:【0-1.0)
第二个同学范围:【1.0-2.0)
第三个同学范围:【2.0-3.0)…
以此类推,当同学被点到的之后修改同学对于的权重,修改为原来的一半即可。
/*
* 需求:
* 用程序实现随机点名器。
* 要求点到的学生再次被点到的概率下降一半
* 需要读取本地文件中的数据
* 数据格式:XXX-男-20-1.0
* 分别表示:姓名-性别-年龄-权重占比
* */
代码实现:
创建学生类:
package RamdomRollCaller;
public class Student {
private String name;
private String gender;
private int age;
private double weight;
public Student() {
}
public Student(String name, String gender, int age, double weight) {
this.name = name;
this.gender = gender;
this.age = age;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
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;
}
@Override
public String toString() {
return name + "-" + gender + "-" + age + "-" + weight;
}
}
完整代码实现:
package RamdomRollCaller;
import java.io.*;
import java.lang.reflect.AnnotatedArrayType;
import java.util.ArrayList;
import java.util.Arrays;
public class RollCallerDemo5 {
/*
* 需求:
* 用程序实现随机点名器。
* 要求点到的学生再次被点到的概率下降一半
* 需要读取本地文件中的数据
* 数据格式:XXX-男-20-1.0
* 分别表示:姓名-性别-年龄-权重占比
* */
public static void main(String[] args) throws IOException {
//关联本地文件
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
//创建集合用于临时存储数据
ArrayList<String> nameTempList = new ArrayList<>();
//创建集合存储学生对象便于管理和操作
ArrayList<Student> students = new ArrayList<>();
//读数据
String str = "";
while ((str = br.readLine()) != null) {
nameTempList.add(str);
}
//关流
br.close();
//获取数据内容并创建学生对象添加到集合
for (String nameStr : nameTempList) {
String[] arr = nameStr.split("-");
students.add(new Student(arr[0], arr[1], Integer.parseInt(arr[2]), Double.parseDouble(arr[3])));
}
//计算总比重
double weight = 0;
for (Student student : students) {
weight = weight + student.getWeight();
}
//计算每个人的实际占比
double[] arr = new double[students.size()];
int index = 0;
for (Student student : students) {
arr[index] = student.getWeight() / weight;
index++;
}
//计算每个人的占比范围
for (int i = 1; i < arr.length; i++) {
arr[i] = arr[i] + arr[i - 1];
}
//制造0-1.0的随机数
double random = Math.random();
//二分查找,计算出随机数应存入的位置
//细节:调用Arrays的二分查找方法,该方法返回负的索引值减一
// 要得到最终索引需要反向操作,用返回值的相反数减一得到被点到的学生对象在students集合中的位置
int i = -Arrays.binarySearch(arr, random) - 1;
Student result = students.get(i);
System.out.println(result.getName());
//修改该学生的占比
double w = result.getWeight() / 2;
result.setWeight(w);
//将修改后的数据写到源文件中
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
for (Student s : students) {
bw.write(s.toString());
bw.newLine();
}
//关流
bw.close();
}
}
运行效果:
随机到的同学占比修改为0.5,再次运行程序:
还没有评论,来说两句吧...