n个学生分配n个座位,随机分配,要求学号相邻座位不相邻。

70行以内java代码实现,n个学生分配n个座位,随机分配,要求学号相邻座位不相邻。


我是采用二维数组来模拟问题!

本次没考虑先随机选学生,再随机分配座位,而是考虑的按顺序来给学生分配座位,座位是随机分配的,不过这么一来
不需要考虑他后边的同学的座位编号相邻或相同了,较为简单。由于采用了while循环,而且是随机分配,如果数据量
过小,会导致死循环,即不会终止,因为比方:如果随机数的范围为0,1,2,那么看似是随机分配的,实际上,它可能
连续好多次都是同一个数字,导致一直运行中,停不下来。如果数据量大了,反而降低了这种可能。(实测,就是这么
一回事!一开始程序卡住了,我还以为代码有bug,后来一想。。。才明白!)
/**
 * n个学生分配n个座位,随机分配,要求学号相邻座位不相邻。 
 * 分配前 
 * 学生学号: 1 2 3 4 5 。。。n 
 * 座位编号: 0 0 0 0 0 。。。0
 * 
 * 分配后 
 * 学生学号: 1 2 3 4 5 
 * 座位编号: 4 1 3 5 2
 * 
 * 采用二维数组来处理:wrap[2][n] 
 * 第一行 存放学生学号: wrap[0][0] wrap[0][1] wrap[0][2] ... wrap[0][n-1] 
 * 第二行 存放座位编号: wrap[1][0] wrap[1][1] wrap[1][2] ... wrap[1][n-1]
 */
 
package study;
import java.util.ArrayList;
import java.util.Random;

public class Main {
	public static void main(String[] args) {
		int n = 5;// 学生总人数or座位总数量
		int[][] wrap = new int[2][n];
		for (int i = 0; i < n; i++) {
			wrap[0][i] = i + 1;// 初始化学生学号
			wrap[1][i] = 0; // 初始化座位编号
		}
		System.out.println("排位前:");
		for (int i = 0; i < n; i++) {// 排位前打印
			if(wrap[0][i]<10) {
				System.out.print("学生学号:   " + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");	
			}else {
				System.out.print("学生学号:" + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");
			}
			if ((i + 1) % 4 == 0) {
				System.out.println();
			}
		}
		System.out.println();
		System.out.println();
		Random random = new Random();
		int seatId = 0;
		ArrayList<Integer> arrayList = new ArrayList<Integer>();// 存放已分配出去的座位编号
		for (int i = 0; i < n; i++) {// 按学号顺序依次分配座位号(座位号从1开始,即1,2,3, 。。。,n)
			seatId = random.nextInt(n) + 1;
			if (i == 0) {// 第一个学生,初次分配,不需要考虑邻座或座位已分配情况
				wrap[1][i] = seatId;
				arrayList.add(seatId);
			} else {
				int preSeatId = wrap[1][i - 1];// 待分配座位的学生的前一个学生座位编号
				while (arrayList.contains(seatId) || (preSeatId + 1 == seatId) || (preSeatId - 1 == seatId)) {// 当前产生的待分配的随机座位号已被分配出去,或与前一个学生座位编号相邻
					seatId = random.nextInt(n) + 1;
				}
				wrap[1][i] = seatId;
				arrayList.add(seatId);
			}
		}
		System.out.println("排位后:");
		for (int i = 0; i < n; i++) {// 排位后打印
			if(wrap[0][i]<10) {
				if(wrap[1][i]<10) {
					System.out.print("学生学号:   " + wrap[0][i] + ",座位编号:   " + wrap[1][i] + "; ");
				}
				else {
					System.out.print("学生学号:   " + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");
				}
			}else {
				if(wrap[1][i]<10) {
					System.out.print("学生学号:" + wrap[0][i] + ",座位编号:   " + wrap[1][i] + "; ");
				}
				else {
					System.out.print("学生学号:" + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");
				}
			}
			if ((i + 1) % 4 == 0) {
				System.out.println();
			}
		}
	}
}


优化前(打印结果对齐方式出现错位):

package study;
import java.util.ArrayList;
import java.util.Random;

public class Main {
	public static void main(String[] args) {
		int n = 5;// 学生总人数or座位总数量
		int[][] wrap = new int[2][n];
		for (int i = 0; i < n; i++) {
			wrap[0][i] = i + 1;// 初始化学生学号
			wrap[1][i] = 0; // 初始化座位编号
		}
		System.out.println("排位前:");
		for (int i = 0; i < n; i++) {// 排位前打印
			System.out.print("学生学号:" + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");
			if ((i + 1) % 3 == 0) {
				System.out.println();
			}
		}
		System.out.println();
		System.out.println();
		Random random = new Random();
		int seatId = 0;
		ArrayList<Integer> arrayList = new ArrayList<Integer>();// 存放已分配出去的座位编号
		for (int i = 0; i < n; i++) {// 按学号顺序依次分配座位号(座位号从1开始,即1,2,3, 。。。,n)
			seatId = random.nextInt(n) + 1;
			if (i == 0) {// 第一个学生,初次分配,不需要考虑邻座或座位已分配情况
				wrap[1][i] = seatId;
				arrayList.add(seatId);
			} else {
				int preSeatId = wrap[1][i - 1];// 待分配座位的学生的前一个学生座位编号
				while (arrayList.contains(seatId) || (preSeatId + 1 == seatId) || (preSeatId - 1 == seatId)) {// 当前产生的待分配的随机座位号已被分配出去,或与前一个学生座位编号相邻
					seatId = random.nextInt(n) + 1;
				}
				wrap[1][i] = seatId;
				arrayList.add(seatId);
			}
		}
		System.out.println("排位后:");
		for (int i = 0; i < n; i++) {// 排位后打印
			System.out.print("学生学号:" + wrap[0][i] + ",座位编号:" + wrap[1][i] + "; ");
			if ((i + 1) % 3 == 0) {
				System.out.println();
			}
		}
	}
}


运行结果:

测试用例1:在这里插入图片描述
测试用例2:在这里插入图片描述

优化前:

测试用例1:
在这里插入图片描述
测试用例2:在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值