S错位形分班算法如何实现

lingyuzhishui 2009-06-14 12:36:08
基本按照S形分班,但是又要求每次循环都要错开一位,请问如何来实现将相应的名次放入各个班级?或者是将班级号插入对应的各个名次中?规律如下所示:(不考虑男女比例)

名 次
一班:1 16 24 31 39 46 54 61

二班:2 15 17 30 40 45 55 60

三班:3 14 18 29 33 44 56 59

四班:4 13 19 28 34 43 49 58

五班:5 12 20 27 35 42 50 57

六班:6 11 21 26 36 41 51 64

七班:7 10 22 25 37 48 52 63

八班:8 9 23 32 38 47 53 62
...全文
130 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
我爱程序 2011-04-11
  • 打赏
  • 举报
回复
你们写的太复杂了

--获取对应数量
Select @ManNum = IsNull(Max(OrderNo),0) From ##ManTable
Select @WomanNum = IsNull(Max(OrderNo),0) From ##WomanTable
Set @Max = Case When @ManNum > @WomanNum Then @ManNum Else @WomanNum End --获取最大的分配值
Set @CircleCount = @Max / (@ClassNum * 2) --初始循环次数
Set @Step = 1
While(@Step <= @CircleCount) --首先分配,不考虑区域限制
Begin
--计算公式:班级OrderNo + (步骤@Step - 1)*班级总数@ClassNum 从首正排序插入班级
Update #ClassTable Set ManNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##ManTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##ManTable Set CCode = a.CCode From #ClassTable a,##ManTable b Where b.OrderNo = a.OrderNo + (@Step - 1) * @ClassNum
And b.CCode = '' And a.ManNum <= @ManNum
Update #ClassTable Set WomanNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##WomanTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##WomanTable Set CCode = a.CCode From #ClassTable a,##WomanTable b,@TempArea c Where b.OrderNo = a.OrderNo + (@Step - 1) * @ClassNum
And b.CCode = '' And a.WomanNum <= @WomanNum
--计算公式:最大男生或者女生@ManNum或@WomanNum - (班级OrderNo + (步骤@Step - 1)*班级总数@ClassNum - 1) 从尾倒排序插入班级
Update #ClassTable Set ManNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##ManTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##ManTable Set CCode = a.CCode From #ClassTable a,##ManTable b Where b.OrderNo = @ManNum - (a.OrderNo + (@Step - 1) * @ClassNum - 1)
And b.CCode = '' And a.ManNum <= @ManNum
Update #ClassTable Set WomanNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##WomanTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##WomanTable Set CCode = a.CCode From #ClassTable a,##WomanTable b Where b.OrderNo = @WomanNum - (a.OrderNo + (@Step - 1) * @ClassNum - 1)
And b.CCode = '' And a.WomanNum <= @WomanNum
Set @Step = @Step + 1
End
lingyuzhishui 2009-06-15
  • 打赏
  • 举报
回复
太感谢cloudfang了,请问如何将结果转换为数据库中的数据,将名次列为一列,班号对应的为一列,谢谢大侠了
gawexi 2009-06-15
  • 打赏
  • 举报
回复
小王。我再来个java版的,呵呵。

先放结果吧。
list1: 1 16 24 31 39 46 54 61 69 76 84 91 99 106 114 121 129 144 152 159 167 174 182 189 197

list2: 2 15 17 30 40 45 55 60 70 75 85 90 100 105 115 128 130 143 145 158 168 173 183 188 198

list3: 3 14 18 29 33 44 56 59 71 74 86 89 101 112 116 127 131 142 146 157 161 172 184 187 199

list4: 4 13 19 28 34 43 49 58 72 73 87 96 102 111 117 126 132 141 147 156 162 171 177 186 200

list5: 5 12 20 27 35 42 50 57 65 80 88 95 103 110 118 125 133 140 148 155 163 170 178 185 193

list6: 6 11 21 26 36 41 51 64 66 79 81 94 104 109 119 124 134 139 149 154 164 169 179 192 194

list7: 7 10 22 25 37 48 52 63 67 78 82 93 97 108 120 123 135 138 150 153 165 176 180 191 195

list8: 8 9 23 32 38 47 53 62 68 77 83 92 98 107 113 122 136 137 151 160 166 175 181 190 196

不知道是不是满足你得要求。

source:

import java.util.ArrayList;

/**
* class grouping
* @author gwx
* @since 2009/06/15
* @version v1.0
*/
public class TestSclass {

/** class1 ~ class8 */
ArrayList<Integer> list1;
ArrayList<Integer> list2;
ArrayList<Integer> list3;
ArrayList<Integer> list4;
ArrayList<Integer> list5;
ArrayList<Integer> list6;
ArrayList<Integer> list7;
ArrayList<Integer> list8;

/** ranking list */
ArrayList<Integer> list;

int x = 0; // which class
int y = 0; // which column for all
/** every two columns were one group */
int z = 0; // which group

public void init(){

list1 = new ArrayList<Integer>();
list2 = new ArrayList<Integer>();
list3 = new ArrayList<Integer>();
list4 = new ArrayList<Integer>();
list5 = new ArrayList<Integer>();
list6 = new ArrayList<Integer>();
list7 = new ArrayList<Integer>();
list8 = new ArrayList<Integer>();
list = new ArrayList<Integer>();

for(int i = 1;i<=200;i++){
list.add(i);
}
}

/**
* class grouping
*/
public void replaceclass(){

for( int i : list){

x = (i-1)%8; //remainder 0 1 2 3 4 5 6 7
y = (i-1)/8; //quotient 0 1 2 3 4 5 6 7 8 9 10 11...
z = y/2; //y quotient 0 1 2 3 4 5

if(y%2 == 0){ //0 1 0 1 0 1 0 1 0 1 0 1 which column in a group

x = x+z;
setlist(i);
} else if(y%2 == 1){

x = 7-x-z;
if(x<0){

x = 8 + x%8;
}
setlist(i);
}
}
}

/**
* add ranking into class
* @param i
*/
public void setlist(int i){

if(x >= 8){

x = x%8;
}

if(x==0){

list1.add(i);
}else if(x==1){

list2.add(i);
}else if(x==2){
list3.add(i);
}else if(x==3){

list4.add(i);
}else if(x==4){

list5.add(i);
}else if(x==5){

list6.add(i);
}else if(x==6){

list7.add(i);
}else if(x==7){

list8.add(i);
}
}

/**
* out print
*/
public void out(){

System.out.print("list1:");
for(int i : list1){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list2:");
for(int i : list2){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list3:");
for(int i : list3){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list4:");
for(int i : list4){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list5:");
for(int i : list5){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list6:");
for(int i : list6){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list7:");
for(int i : list7){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list8:");
for(int i : list8){

System.out.print(" "+i);
}
System.out.print("\n");
}

/**
* main
* @param args
*/
public static void main(String[] args) {

TestSclass ts = new TestSclass();
ts.init();
ts.replaceclass();
ts.out();
}
}
lingyuzhishui 2009-06-15
  • 打赏
  • 举报
回复
感谢大家,感谢cloudfang,以后请大家多多指教
cloudfang 2009-06-15
  • 打赏
  • 举报
回复
错位步骤代码做个调整

/// <summary>
/// 错位
/// </summary>
/// <param name="AllGroup">完成分组步骤的分组</param>
/// <returns>完成错位步骤的分组</returns>
private ArrayList MoveGroup(ArrayList AllGroup)
{
for (int i = 0; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
int MoveIndex = Group.Count / 2;
int MoveCount = i % MoveIndex; //移动次数
for (int j = 0; j < MoveCount; j++)
{
int Move = Convert.ToInt32(Group[MoveIndex - 1]);
Group.RemoveAt(MoveIndex-1);
Group.Insert(0, Move);
Move = Convert.ToInt32(Group[Group.Count - 1]);
Group.RemoveAt(Group.Count - 1);
Group.Insert(MoveIndex, Move);
}
}
return AllGroup;
}
cloudfang 2009-06-15
  • 打赏
  • 举报
回复
步骤:分组、错位、折叠分班,为方便理解,各步分开写。
代码在VS2008下测试通过,直接复制即可运行。
详细代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

/// <summary>
/// 分组
/// </summary>
/// <param name="ClassNum">班级数</param>
/// <param name="StudentNum">学生数</param>
/// <returns>完成分组步骤的分组</returns>
private ArrayList DivideGroup(int ClassNum, int StudentNum)
{
//先把所有学生分组
ArrayList AllGroup = new ArrayList(); //存放所有分组
int GroupNum = ClassNum * 2; //每组学生数
int count = StudentNum % GroupNum == 0 ? StudentNum / GroupNum : StudentNum / GroupNum + 1; //组数
//把学生加入分组
for (int i = 1; i < count + 1; i++)
{
ArrayList Group = new ArrayList();
int StartIndex=GroupNum * (i - 1) + 1;
int EndIndex=GroupNum * i + 1;
for (int j = StartIndex; j < EndIndex; j++)
{
Group.Add(j > StudentNum ? 0 : j); //不足就用0代替
}
AllGroup.Add(Group);
}
return AllGroup;
}

/// <summary>
/// 错位
/// </summary>
/// <param name="AllGroup">完成分组步骤的分组</param>
/// <returns>完成错位步骤的分组</returns>
private ArrayList MoveGroup(ArrayList AllGroup)
{
//第一组不错位,所以从第二组开始
for (int i = 1; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
for (int j = 0; j < i; j++) //移动几次
{
int MoveIndex = Group.Count / 2;
int Move = Convert.ToInt32(Group[MoveIndex - 1]);
Group.RemoveAt(MoveIndex-1);
Group.Insert(0, Move);
Move = Convert.ToInt32(Group[Group.Count - 1]);
Group.RemoveAt(Group.Count - 1);
Group.Insert(MoveIndex, Move);
}
}
return AllGroup;
}

/// <summary>
/// 折叠分班
/// </summary>
/// <param name="AllGroup">完成错位步骤的分组</param>
/// <returns></returns>
private Hashtable DivideClass(ArrayList AllGroup)
{
Hashtable htClass=new Hashtable();
for (int i = 0; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
//对于每个分组,第一个和最后一个属于一班,第二个和倒数第二个属于二班.......循环一半即可
int ClassNum=Group.Count / 2;
for (int j = 0; j < ClassNum; j++)
{
ArrayList Class = new ArrayList();
int ClassNo = (j + 1) % ClassNum == 0 ? ClassNum : (j + 1) % ClassNum;
if (htClass[ClassNo] == null)
{
Class.Add(Group[j]);
Class.Add(Group[Group.Count - 1 - j]);
htClass.Add(ClassNo, Class);
}
else
{
Class = (ArrayList)htClass[ClassNo];
Class.Add(Group[j]);
Class.Add(Group[Group.Count - 1 - j]);
}
}
}
return htClass;
}

private void button1_Click(object sender, EventArgs e)
{
Hashtable ht = DivideClass(MoveGroup(DivideGroup(8, 63)));
StringBuilder sb = new StringBuilder();
for (int i = 1; i < 9; i++)
{
ArrayList Class = (ArrayList)ht[i];
sb.Append(i.ToString() + "班:");
for (int j = 0; j < Class.Count; j++)
{
sb.Append(" " + Class[j].ToString());
}
sb.Append("\r\n");
}
this.richTextBox1.Text = sb.ToString();
}
}
}

yingzhilian2008 2009-06-14
  • 打赏
  • 举报
回复
帮顶

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧