import?java.util.ArrayList;
創(chuàng)新互聯(lián)長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為汪清企業(yè)提供專業(yè)的網(wǎng)站制作、做網(wǎng)站,汪清網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
import?java.util.List;
import?java.util.Random;
/**
*?抽獎(jiǎng)工具類,概率和可以不等于1
*?概率為百分?jǐn)?shù)去掉百分號的部分,如10%,則為10
*?抽獎(jiǎng)操作如下:
*?1.輸入抽獎(jiǎng)概率集合,【抽獎(jiǎng)概率集合為{10.0,?20.0,?30.0}】
*?2.生成連續(xù)集合,???????【生成的連續(xù)集合為{(0.0,?10.0],(10.0,?30.0],(30.0,?60.0]}】
*?3.生成隨機(jī)數(shù),??????????【生成方法為?random.nextDouble()?*?maxElement】
*?4.判斷隨機(jī)數(shù)在哪個(gè)區(qū)間內(nèi),返回該區(qū)間的index【生成了隨機(jī)數(shù)12.001,則它屬于(10.0,?30.0],返回?index?=?1】
*
*/
public?class?LotteryUtil?{
/**
*?定義一個(gè)連續(xù)集合
*?集合中元素x滿足:(minElement,maxElement]
*?數(shù)學(xué)表達(dá)式為:minElement??x?=?maxElement
*
*/
public?class?ContinuousList?{
private?double?minElement;
private?double?maxElement;
public?ContinuousList(double?minElement,?double?maxElement){
if(minElement??maxElement){
throw?new?IllegalArgumentException("區(qū)間不合理,minElement不能大于maxElement!");
}
this.minElement?=?minElement;
this.maxElement?=?maxElement;
}
/**
*?判斷當(dāng)前集合是否包含特定元素
*?@param?element
*?@return
*/
public?boolean?isContainKey(double?element){
boolean?flag?=?false;
if(element??minElement??element?=?maxElement){
flag?=?true;
}
return?flag;
}
}
private?ListContinuousList?lotteryList;???//概率連續(xù)集合
private?double?maxElement;??????????????????//這里只需要最大值,最小值默認(rèn)為0.0
/**
*?構(gòu)造抽獎(jiǎng)集合
*?@param?list?為獎(jiǎng)品的概率
*/
public?LotteryUtil(ListDouble?list){
lotteryList?=?new?ArrayListContinuousList();
if(list.size()?==?0){
throw?new?IllegalArgumentException("抽獎(jiǎng)集合不能為空!");
}
double?minElement?=?0d;
ContinuousList?continuousList?=?null;
for(Double?d?:?list){
minElement?=?maxElement;
maxElement?=?maxElement?+?d;
continuousList?=?new?ContinuousList(minElement,?maxElement);
lotteryList.add(continuousList);
}
}
/**
*?進(jìn)行抽獎(jiǎng)操作
*?返回:獎(jiǎng)品的概率list集合中的下標(biāo)
*/
public?int?randomColunmIndex(){
int?index?=?-1;
Random?r?=?new?Random();
double?d?=?r.nextDouble()?*?maxElement;??//生成0-1間的隨機(jī)數(shù)
if(d?==?0d){
d?=?r.nextDouble()?*?maxElement;?????//防止生成0.0
}
int?size?=?lotteryList.size();
for(int?i?=?0;?i??size;?i++){
ContinuousList?cl?=?lotteryList.get(i);
if(cl.isContainKey(d)){
index?=?i;
break;
}
}
if(index?==?-1){
throw?new?IllegalArgumentException("概率集合設(shè)置不合理!");
}
return?index;
}
public?double?getMaxElement()?{
return?maxElement;
}
public?ListContinuousList?getLotteryList()?{
return?lotteryList;
}
public?void?setLotteryList(ListContinuousList?lotteryList)?{
this.lotteryList?=?lotteryList;
}
}
該工具類的基本思想是,將抽獎(jiǎng)概率分布到數(shù)軸上,如現(xiàn)有三個(gè)抽獎(jiǎng)概率10、20、30,將三者依次添加到概率集合中,則構(gòu)造的數(shù)軸為:0~10范圍內(nèi)表示概率10,10~30范圍內(nèi)表示概率為20,30~60范圍內(nèi)表示概率為30,數(shù)軸上的長度對應(yīng)著相應(yīng)的概率。由這種處理方式可知,概率總和并不需要等于1。該工具類的成功與否在于Random.nextDouble()能否等概率地生成0~1之間的任意一個(gè)數(shù)。
對該抽獎(jiǎng)工具進(jìn)行測試,測試類如下:
[java]?view plain?copy
package?com.lottery;
import?java.util.ArrayList;
import?java.util.HashMap;
import?java.util.List;
import?java.util.Map;
import?java.util.Map.Entry;
class?Result{
private?int?index;
private?int?sumTime;
private?int?time;
private?double?probability;
private?double?realProbability;
public?int?getIndex()?{
return?index;
}
public?void?setIndex(int?index)?{
this.index?=?index;
}
public?int?getTime()?{
return?time;
}
public?void?setTime(int?time)?{
this.time?=?time;
}
public?int?getSumTime()?{
return?sumTime;
}
public?void?setSumTime(int?sumTime)?{
this.sumTime?=?sumTime;
}
public?double?getProbability()?{
return?probability;
}
public?double?getRealProbability()?{
return?realProbability;
}
public?void?setRealProbability(double?realProbability)?{
this.realProbability?=?realProbability;
}
public?Result(){
}
public?Result(int?index,?int?sumTime,?int?time,?double?realProbability)?{
this.setIndex(index);
this.setTime(time);
this.setSumTime(sumTime);
this.setRealProbability(realProbability);
}
public?String?toString(){
return?"索引值:"?+?index?+?",抽獎(jiǎng)總數(shù):"?+?sumTime?+?",抽中次數(shù):"?+?time?+?",概率:"
+?realProbability?+?",實(shí)際概率:"?+?(double)time/sumTime;
}
}
public?class?TestLottery?{
static?final?int?TIME?=?100000;
public?static?void?iteratorMap(MapInteger,?Integer?map,?ListDouble?list){
for(EntryInteger,?Integer?entry?:?map.entrySet()){
int?index?=?entry.getKey();
int?time??=?entry.getValue();
Result?result?=?new?Result(index,?TIME,?time,?list.get(index));
System.out.println(result);
}
}
public?static?void?main(String[]?args)?{
//構(gòu)造概率集合
ListDouble?list?=?new?ArrayListDouble();
list.add(20d);
list.add(80d);
list.add(50d);
list.add(30d);
LotteryUtil?ll?=?new?LotteryUtil(list);
double?sumProbability?=?ll.getMaxElement();
MapInteger,?Integer?map?=?new?HashMapInteger,?Integer();
for(int?i?=?0;?i??TIME;?i++){
int?index?=?ll.randomColunmIndex();
if(map.containsKey(index)){
map.put(index,?map.get(index)?+?1);
}else{
map.put(index,?1);
}
}
for(int?i?=?0;?i??list.size();?i++){
double?probability?=?list.get(i)?/?sumProbability;
list.set(i,?probability);
}
iteratorMap(map,?list);
}
}
運(yùn)行結(jié)果:
由結(jié)果可知,抽獎(jiǎng)100000時(shí), 得到的實(shí)際概率基本與正式概率相當(dāng)。
以下說明此類調(diào)用方式:
[java]?view plain?copy
public?LotteryUtil(ListDouble?list)
說明:構(gòu)造方法,傳入?yún)?shù)為一個(gè)概率集合
[java]?view plain?copy
public?int?randomColunmIndex()
功能:進(jìn)行抽獎(jiǎng)操作,返回List集合的索引下標(biāo),此下標(biāo)對應(yīng)的概率的獎(jiǎng)品即為抽中的獎(jiǎng)品
中獎(jiǎng)率 1%,每人抽 10 次,也就是說 10 個(gè)人就可以抽 100 次,概率上來說 10 個(gè)人必中獎(jiǎng)?假設(shè)邏輯是這樣的,可以這樣設(shè)計(jì):
1、先寫定義一個(gè)表示概率的數(shù)組 ratio,這個(gè)數(shù)組最多可以存 100 個(gè)數(shù)字,每個(gè)數(shù)字的值不能重復(fù),范圍是 0 到 100,表示 100%?,F(xiàn)在你的中獎(jiǎng)率是 1%,那么就存一個(gè)數(shù)字。
2、定義一個(gè)是否中將的布爾型變量 win;
每次抽獎(jiǎng)用隨機(jī)正整數(shù)對 100 取余,再將結(jié)果拿到 ratio 數(shù)組中查找,如果找到就將 win 賦值為 true,表示中獎(jiǎng)。如果沒找到就對 win 賦值為 false,表示沒有中獎(jiǎng)。
public class Test {
public static void main(String[] args) {
int chance = 100;// 中獎(jiǎng)概率,百分之1就是100,千分之一就是1000
double b = Math.random() * chance;
int i = (int) b;
if (i 1) {
System.out.println("中獎(jiǎng)");
}
}
}
抽取問題, 重點(diǎn)是 同一個(gè)學(xué)號不能重復(fù)被抽取.
解決辦法很多,
比如數(shù)組可以使用下標(biāo)來標(biāo)記,號碼是否被使用,使用了就繼續(xù)下一次抽取
也可以使用集合來抽取,把集合順序打亂,然后隨便抽幾個(gè)就可以了
參考代碼:數(shù)組法
import?java.util.Random;
public?class?Test?{
public?static?void?main(String[]?args)?{
int?stuNums=30;
int[]?nums=new?int[stuNums];//存儲學(xué)號的數(shù)組
boolean[]?flags=new?boolean[stuNums];//標(biāo)記,用于標(biāo)記對應(yīng)下標(biāo)的學(xué)號是否已經(jīng)被抽取過了
for?(int?i?=?0;?i??stuNums;?i++)?{
nums[i]=i+1;//給學(xué)號賦值
}
Random?r=new?Random();
while(true){
int?index?=?r.nextInt(stuNums);
if(!flags[index]){
System.out.println("A等:"+nums[index]);
flags[index]=true;?//標(biāo)記已經(jīng)被使用過了
break;
}
}
for?(int?i?=?0;?i??2;?i++)?{
int?index?=?r.nextInt(stuNums);
if(!flags[index]){
System.out.println("B等:"+nums[index]);
flags[index]=true;
}else{
i--;//如果已經(jīng)被抽取過了?,那么i建議,再次循環(huán)
}
}
for?(int?i?=?0;?i??3;?i++)?{
int?index?=?r.nextInt(stuNums);
if(!flags[index]){
System.out.println("c等:"+nums[index]);
flags[index]=true;
}else{
i--;
}
}
}
}
集合法
import?java.util.ArrayList;
import?java.util.Collections;
public?class?Test2?{
public?static?void?main(String[]?args)?{
int?stuNums=20;
ArrayListInteger?list=new?ArrayListInteger();
for?(int?i?=?0;?i??stuNums;?i++)?{
list.add(i+1);
}
System.out.println("有序"+list);
Collections.shuffle(list);//打亂順序
System.out.println("亂序"+list);
System.out.println("A等"+list.get(0));
System.out.println("B等"+list.get(1));
System.out.println("B等"+list.get(2));
System.out.println("C等"+list.get(3));
System.out.println("C等"+list.get(4));
System.out.println("C等"+list.get(5));
}
}
import?java.awt.EventQueue;
import?java.awt.TextArea;
import?java.awt.TextField;
import?java.awt.event.ActionEvent;
import?java.awt.event.ActionListener;
import?java.util.Random;
import?javax.swing.JButton;
import?javax.swing.JFrame;
import?javax.swing.JLabel;
import?javax.swing.JPanel;
import?javax.swing.JTextArea;
import?javax.swing.JTextField;
import?javax.swing.border.EmptyBorder;
public?class?LuckySelect?extends?JFrame?{
private?JPanel?contentPane;
private?JTextField?textFieldA;
private?JTextField?textFieldB;
private?JTextField?textFieldC;
private?TextField?textField;
private?JTextField?textFieldResult;
private?JTextArea?textArea;
/**
?*?Launch?the?application.
?*/
public?static?void?main(String[]?args)?{
EventQueue.invokeLater(new?Runnable()?{
public?void?run()?{
try?{
LuckySelect?frame?=?new?LuckySelect();
frame.setVisible(true);
}?catch?(Exception?e)?{
e.printStackTrace();
}
}
});
}
/**
?*?Create?the?frame.
?*/
public?LuckySelect()?{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,?100,?450,?251);
contentPane?=?new?JPanel();
contentPane.setBorder(new?EmptyBorder(5,?5,?5,?5));
contentPane.setLayout(null);
setContentPane(contentPane);
JLabel?lblA?=?new?JLabel("A");
lblA.setBounds(10,?128,?54,?15);
contentPane.add(lblA);
JLabel?lblB?=?new?JLabel("B");
lblB.setBounds(124,?128,?54,?15);
contentPane.add(lblB);
JLabel?lblC?=?new?JLabel("C");
lblC.setBounds(254,?128,?54,?15);
contentPane.add(lblC);
textFieldA?=?new?JTextField();
textFieldA.setBounds(30,?125,?66,?21);
contentPane.add(textFieldA);
textFieldA.setColumns(10);
textFieldB?=?new?JTextField();
textFieldB.setColumns(10);
textFieldB.setBounds(149,?125,?66,?21);
contentPane.add(textFieldB);
textFieldC?=?new?JTextField();
textFieldC.setColumns(10);
textFieldC.setBounds(264,?125,?66,?21);
contentPane.add(textFieldC);
textField?=?new?TextField();
textField.setBounds(98,?167,?157,?21);
contentPane.add(textField);
textField.setColumns(10);
textFieldResult?=?new?JTextField();
textFieldResult.setBounds(280,?167,?66,?21);
contentPane.add(textFieldResult);
textFieldResult.setColumns(10);
textFieldA.setText("10");
textFieldB.setText("10");
textFieldC.setText("10");
JButton?button?=?new?JButton("\u62BD\u5956");
button.addActionListener(new?ActionListener()?{
public?void?actionPerformed(ActionEvent?e)?{
select();
}
});
button.setBounds(0,?166,?93,?23);
contentPane.add(button);
textArea?=?new?JTextArea();
textArea.setBounds(30,?31,?306,?83);
contentPane.add(textArea);
}
protected?void?select()?{
//?TODO?Auto-generated?method?stub
int?aNum?=?Integer.decode(textFieldA.getText());
int?bNum?=?Integer.decode(textFieldB.getText());
int?cNum?=?Integer.decode(textFieldB.getText());
Random?r?=?new?Random();
int?random?=?r.nextInt(aNum?+?bNum?+?cNum);
if(random?=?aNum){
textFieldA.setText(Integer.toString(Integer.decode(textFieldA.getText())?-?1));
textArea.append(Integer.toString(random)?+?"抽中了A\n");
}else?if(random?=?aNum?+?bNum){
textFieldB.setText(Integer.toString(Integer.decode(textFieldB.getText())?-?1));
textArea.append(Integer.toString(random)?+?"抽中了B\n");
}else?if(random?=?aNum?+?bNum?+?cNum){
textFieldC.setText(Integer.toString(Integer.decode(textFieldC.getText())?-?1));
textArea.append(Integer.toString(random)?+?"抽中了C\n");
}
}
}