首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

S形分班算法怎么实现

2012-03-07 
求助:S形分班算法如何实现基本按照S形分班,但是又要求每次循环都要错开一位,请问如何来实现将相应的名次放

求助:S形分班算法如何实现
基本按照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

[解决办法]
给出一个简单的java实现,方法有三个参数,分别是学生总数,班级总数,和排序参数(true为顺序排列,false为倒排序)。
其中顺序排序和倒排序是以班级序号为依据。


public class studentDivByClasses {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* variable order,if order equals true,the function divideByClass can order data from no.1 class to last class
* if not,then do that on opposite direction
*/
boolean order = true;
int test[][] = divideByClass(67,7,order);// variable 67 and 7 are test
String str = "顺序";
if(!order){
str = "倒序";
}
//output result
for(int i=0;i<7;i++){
for(int j=0;j<test[i].length;j++){
int x = test[i][j];
if(x != 0){
System.out.println("进行"+str+"排列的结果:第"+(i+1)+"班被分配的第"+(j+1)+"位学生总体排名为:"+x+"");
}
}
}
}

public static int[][] divideByClass(int stuNum,int classNum,boolean type){
//difine integer Array
int[][] rs = new int[classNum][stuNum/classNum+1];
for(int i=0;i<stuNum;i++){
int x = i%classNum;
int y = i/classNum;
if(!type){
x = classNum-i%classNum-1;
y = i/classNum;
}
rs[x][y]=i+1;
}
return rs;
}
}
[解决办法]
#include<stdio.h>
int a[100][100];
int b[100];
int main()
{
int i,j;
int n,count,num,temp;
count=1;
num=1;
scanf("%d",&n);
for(i=0;i<n;i++) //将数据按S形存入数组中
{
for(j=0;j<n;j++)
{
if(j%2==0)
{
a[i][j]=count+j*n;
}
else
{
a[i][j]=(j+1)*n-count+1;
}
}
count++;
}
for(j=2;j<n;j++)
{
if(j%2==0) //偶数列下错num行
{
for(i=num;i<n;i++)
{
b[i]=a[i-num][j];
}
for(i=0;i<num;i++)
{
a[i][j]=a[(i+n-num)%n][j];
}
for(i=num;i<n;i++)
{
a[i][j]=b[i];
}
}
else //奇数列上错num行
{
for(i=n-1;i>=n-num;i--)
{
b[i]=a[i-n+num][j];
}
for(i=0;i<n-num;i++)
{
a[i][j]=a[(i+num)%n][j];
}
for(i=n-num;i<n;i++)
{
a[i][j]=b[i];
}
num++; //奇偶列
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
[解决办法]
using namespace std;

template <class T> //最简单的直接移动向量旋转算法
void SlideRotate(T a[], int n, int r);

int main(int argc, char* argv[])
{
const int MAX = 63; //总人数
const int NUMCLASS = 8; //班级数
const int NUMSTU = MAX / NUMCLASS + 1; //每个班级的学生数
int lib[NUMCLASS][NUMSTU] = {0}; //二维数组,用来输出图表


int n = 0; //用来遍历所有的人

while (n < MAX)
{
for (int i=0; i<NUMSTU/2; i++)
{
int tempArr[NUMCLASS] = {0}; //临时数组
for (int j=0; j<NUMCLASS; j++)
{
if (n == MAX) //输出图表
break;
tempArr[j] = ++n;
}
SlideRotate(tempArr, NUMCLASS, NUMSTU-i);
for (int j=0; j<NUMCLASS; j++)
lib[j][2*i] = tempArr[j];

if (n == MAX) //输出图表
break;

for (int j=0; j<NUMCLASS; j++) //临时数组归零
tempArr[j] = 0;
for (int j=NUMCLASS-1; j>=0; j--) //逆序存储
{
if (n == MAX) //输出图表
break;
tempArr[j] = ++n;
}
SlideRotate(tempArr, NUMCLASS, i);
for (int j=0; j<NUMCLASS; j++)
lib[j][2*i+1] = tempArr[j];

if (n == MAX) //输出图表
break;
}
}

for (int i=0; i<NUMSTU; i++)
{
for (int j=0; j<NUMCLASS; j++)
{
cout << lib[i][j] << " ";
}
cout << endl;
}

system("pause");
return 0;
}
//---------------------------------------
/*
函数名称:SlideRotate
函数功能:最简单的直接移动向量旋转算法:先利用一个辅助数组将较短的那一段元素存储起来,
再移动原向量中未另外存储的那部分元素,最后将辅助数组中的元素再复制到正确位置
输入参数:T a[]:需要被旋转的向量
int n:向量的长度
int r:向量左半段长度
输出参数:T a[]:旋转后的向量
返回值:无
*/
template <class T>
void SlideRotate(T a[], int n, int r)
{
if (r < n - r) //如果左半段小于右半段,存储左半段的元素
{
T *buf = new T[r];
for (int i=0; i<r; i++)//存储左半段的元素
buf[i] = a[i];

for (int i=r; i<n; i++)//移动右半段的元素
a[i-r] = a[i];

for (int i=0; i<r; i++)//复制左半段的元素到右半段
a[n-r+i] = buf[i];

delete []buf; 
}
else //否则存储右半段的元素 
{
T *buf = new T[n-r];
for (int i=r; i<n; i++)//存储右半段的元素
buf[i-r] = a[i];

for (int i=r-1; i>=0; i--)//移动左半段的元素
a[i+n-r] = a[i];

for (int i=0; i<n-r; i++)//复制右半段的元素到左半段
a[i] = buf[i];

delete []buf;
}
}

热点排行