站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题随机抽取系统(带算法)请各位指教

随机抽取系统(带算法)请各位指教

摘要: 随机抽取系统(带算法)请各位指教


随机抽取系统(带算法)请各位指教


如果这个算法让各位前辈高手写的话会怎么写?比如我们有20个学生反复进行随机抽取出来作某项工作,每次抽取的人数由不确定(由管理员输入)要求:这次抽到的下次就不抽他了 难点是:比如我们每次抽取6个 三次过后只剩下2个没有被抽取到 这时候如果再继续抽取6个人就需要把剩下2个取出来 然后从令18个再随即抽取6个
让各位写算法你会怎么写?
比如:如果第一次抽了15个,第二次想抽十个 只能这样:剩下5个一定被抽到 然后从已经抽到的上次15个中再选10-5=5个!

大家说下思路,牛的配合代码说下(最好有代码了,代码最有发言权:)
下面是我的做法,大家批判下缺点(估计一点优点都没有) 各个方面,无论巨细,从整体思想到编码设计到变量风格都可以,想在这里学习下高手们的action
拜~~

My MSN: microinsky@hotmail.com 虚心向各位指教! 请不吝赐教!



/**
* 数据库中除了id username password 还有status选项 其中 status=0代表没有演讲的 status=1代表已经演讲
* @numberOfSql()获取当前数据库中总人数
* @author insKy
* @time 2006-11-13 2:18:29
* @version 1.0
* @param list
* @param numOfSelect
* @return
* @throws SQLException
*/


public int numberOfSql()throws SQLException{
Connection conn = null;
Statement st = null;
ResultSet rs = null;
int numOfSql = 0;
try {
conn = getConnection();
String sql = "SELECT COUNT(*) FROM [user] WHERE status=0";
st = conn.createStatement();
rs = st.executeQuery(sql);
rs.next();
numOfSql = rs.getInt(1);
}catch (SQLException e) {
close(rs);
close(st);
e.printStackTrace();
} finally {
close(conn);
}
return numOfSql;
}




/**
* @随机抽取算法
* @author insKy
* @time 2006-11-13 2:18:29
* @version 1.0
* @param list 为数据库所有人员
* @param numOfSelect 为此次抽取的人数 由上个页面input过来
* @return
* @throws SQLException
*/
public List select(List list,int numOfSelect) throws SQLException
{
ArrayList speechList = new ArrayList();
User userTMP = null;
int numOfSql = numberOfSql(); //get the number of status = 0 from Database;
Random rand = new Random();
int numOfRandom = 0;
int numOfallUser = list.size();
if(numOfSql>numOfSelect)
{
//如果没讲的人数大于此次抽取的人数则直接处理
int i = 0;
while(i{
numOfRandom = Math.abs(rand.nextInt())%numOfallUser;
userTMP = (User) list.get(numOfRandom);
if(userTMP.getStatus()==0)
{
speechList.add(userTMP);
userTMP.setStatus(1); //加入本次讲演队列后 改变List中status状态
updateStatus(userTMP.getId(),0); //change the status about DataBase
i++;
}
}//end while
}else if(numOfSql==numOfSelect){
//若正好抽取人数等于未演讲人数 则抽取出人数,然后所有人状态改变
int j = 0;
while(j < list.size() ){
userTMP = (User) list.get(j);
if(userTMP.getStatus()==0){
speechList.add(userTMP);
}
j++;
}// end while

int n = 0;
while(nuserTMP = (User) list.get(n);
updateStatus(userTMP.getId(),1);
n++;
}

}else{
//当没讲的人数小于此次抽取的人数时则先把status=0的入队列 修改其状态
int j = 0;
while(j < list.size() ){
userTMP = (User) list.get(j);
if(userTMP.getStatus()==0){
speechList.add(userTMP);
}
j++;
}// end while
int nCz = numOfSelect - numOfSql;//nCz差值
int k = 0;
while(knumOfRandom = Math.abs(rand.nextInt())%numOfallUser;
userTMP = (User) list.get(numOfRandom);
if(userTMP.getStatus()==1){
speechList.add(userTMP);
userTMP.setStatus(0) ; //加入本次讲演队列后 改变List中status状态,so that we can identify the different
k++;
} //到时候与原来为0的一起改动
}//end while
int n = 0;
while(nuserTMP = (User) list.get(n);
updateStatus(userTMP.getId(),userTMP.getStatus());
n++;
}
}
return speechList; //返回此次演讲的人员
}

/**
* @updateStatus 函数作用是把数据库中的状态值从sts改为相反的改变
* @author insKy
* @time 2006-11-13 2:18:29
* @version 1.0
* @param list
* @param numOfSelect
* @return
* @throws SQLException
*/

public void updateStatus(int id,int sts) throws SQLException
{
sts = (sts + 1)%2;
Connection conn = null;
//PreparedStatement pstmt = null;
Statement st = null;
try {
conn = getConnection();
String sql = "UPDATE [user] SET status="+sts+" WHERE id="+id;
st=conn.createStatement();
st.executeUpdate(sql);
close(st);
} catch (SQLException e) {
close(st);
e.printStackTrace();
} finally {
close(conn);
}
}
}


学习,帮顶。。。


要求:这次抽到的下次就不抽他了 ??
============
这个要求不对吧。你的题目恐怕要求的不止这么多,应该是:每个人抽到的次数最多相差为1。

我提供一个思路:
为每个人建一个属性-抽到过的次数
每次抽的时候,按每个人抽到过的次数可以分成2个队列,一个是次数多的,一个是次数少的。先在次数少的队列中抽,如果数量不足就到次数多的队列中补。然后次数++


有难度,帮顶。


你的算法频繁使用数据库连接没必要 这就是一个算法问题 可以先把数据准备好 然后在内存中作处理


参考一下
package myprojects.pp.test;

import java.util.*;
import java.math.*;
class User
{
public String userId;
public String userName;
}

public class SelectRandom {


public void getList(List totalList,int selectNum)
{
List unSelList = new ArrayList();
List selList = new ArrayList();
if(selectNum>totalList.size())
{
return;
}
unSelList = totalList;
//这里模拟每次取不同的人员 循环几次就代表取几次
//取 7次 每次固定为3人 每次人数这里可以根据实际调整
for (int i = 0; i<7; i++)
{
List userList = getUserList(unSelList,selList,selectNum);
System.out.println ("未选择人员还有 : "+ unSelList.size()+" 第: "+i+" 次结果 : ");
writeResult(userList);
}
}

//打印结果
private void writeResult(List userList)
{
for (int i = 0; i {
User user=(User)userList.get(i);
System.out.println ("userId : "+ user.userId);
}
}

//得到人员列表
private List getUserList(List unSelList,List selList,int selectNum)
{
List userList = new ArrayList();
//如果选择人数小于等于未选择人员列表个数
if(selectNum<=unSelList.size())
{
int i=0;
//如果选择人数还不到要求人员数
while(i++<selectNum)
//随机选择一个人员
int random = getRandom(unSelList.size());
User user = (User)unSelList.get(random);
//加入已选择人员列表
selList.add(user);
//加入此次人员列表
userList.add(user);
//从未选择人员列表中删除
unSelList.remove(random);
}
}
//如果选择人数大于未选择人员列表数
else if(selectNum > unSelList.size())
{
int i=0;
//获取还需从已选择人员列表得到人员数
int needed = selectNum - unSelList.size();
//此次默认为所有未选择人员
userList.addAll(unSelList);
//System.out.println ("======userList addAll: "+ userList.size());
while(i++ {
//随机选择
int random = getRandom(selList.size());
User user = (User)selList.get(random);
//这里是加入未选择人员列表
unSelList.add(user);
//加入此次人员列表
userList.add(user);
//从已选择人员列表删除
selList.remove(random);
}
//交换未选择列表与已选择列表内容
changeContent(unSelList,selList);
}
return userList;
}
//交换内容
private void changeContent(List list1,List list2)
{
System.out.println ("before change size "+ list1.size()+" : "+list2.size() );
int size1 = list1.size();

List tempList = new ArrayList();
for(int i=0;i {
User user = (User)list1.get(i);
tempList.add(user);
}


list1.clear();
for(int i=0;i {
User user = (User)list2.get(i);
list1.add(user);
}
list2.clear();
for(int i=0;i {
User user = (User)tempList.get(i);
list2.add(user);
}

System.out.println ("after change size "+ list1.size()+" : "+list2.size() );

}
//随机选择
private int getRandom(int size)
{
Random rand = new Random();
return Math.abs(rand.nextInt())%size;
}

//模拟取总人员
private List getTotalList()
{
List totalList = new ArrayList();
for(int i=0;i<10;i++)
{
User user = new User();
user.userId=i+"";
user.userName=i+"";
totalList.add(user);
}
System.out.println ("totalList.size() : "+totalList.size());
return totalList;
}

public static void main(String args[])
{
SelectRandom selectR = new SelectRandom();
selectR.getList(selectR.getTotalList(),3);
}
}



to:figoren(figoren)
您说的对,确实频繁使用数据库连接没必要,挺简单的一个问题我把它搞复杂了,一开始的偶的思路更加离谱,尝试全部通过数据库来处理呢,随机生成用数据库自带的随机函数NewID() 然后数据库里设置一个counts计数,通过次数不同来区别每次讲还是没讲。惭愧ing..... 您的程序一目了然,可能是这问题太简单或者偶太菜,您竟然花了一会功夫看明白了偶表达的意思,并且程序实现了。拜一下
确实挺惊讶的,首先偶怀疑大家是否能搞明白偶表达的意思,因为似乎题目的要求有点抽象,偶语言表达能力一般不晓得能否说清楚。然后偶觉得自己程序写的杂乱无比,没想到figoren竟然看了。还有没想到这么快就给出答案....再拜

暂时先不结贴(可以吗?一定会给分的),偶把程序整理下,重写下再放上来,请您再批评

to:hbwhwang(catmiw的ID已经停用,现在用这个)
您说的思路应该就是我数据库里设置counts那种思路了
=========================23:21 2006-11-13 insKy Bupt
大家有什么意见请继续指教! tks^^



↑返回目录
前一篇: j2ee 原代码在哪下
后一篇: 请问如何给textbox赋值?