Files
2026-11-06 01:04:35 +08:00
..
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00
2026-11-06 01:04:35 +08:00

项目三:随机抽签与分组工具

适合第3—4章讲解 QStringList、QSet、随机数、下拉框和按钮状态。

名单的含义

每行代表一位学生。行首和行尾空白会被去掉,空行会被忽略。相同条目不允许重复;同名学生可以写成“01 张三”和“02 张三”。程序不根据姓名猜测是否为同一个人。

打开程序时填入一份虚构的 12 人示例名单,但还没有应用。检查后点击“应用名单”,才能抽签和分组。每次应用都会开始新一轮并清空旧结果。修改名单后,操作按钮暂时禁用,避免操作的实际名单与编辑框不一致。

名单上限为 5000 人,每条最多 100 个字符。这个限制用于及时发现错误粘贴,普通班级无需调整。

不重复抽签

选择本次人数后点击“抽取”。程序保存两份列表:完整名单和剩余候选池。抽到一位学生后,立即从候选池中移除,后续抽签只能从剩余的人中选择。

本轮全部抽完后,抽取按钮不可用。点击“重置抽签”会重新填满候选池并清除抽签记录;已生成的分组保持不变。

课堂上可以先用 A、B、C 三人演示:抽出 B 后候选池只剩 A、C。让学生解释为什么不能每次都从完整名单随机选择。

随机分组

分组始终使用全部已应用名单,与抽签结果无关。

有两种参数:

  • 每组最多人数:先用向上取整计算需要几组,再平均分配。
  • 分成几组:直接指定组数,组数不能超过人数。

例如 12 人、每组最多 5 人,需要 3 组。为了平衡人数,结果是每组 4 人。这个参数表示人数上限,不要求先装满一组再分下一组。

程序先用 Fisher–Yates 算法打乱名单,再按组号轮流分配。每人恰好出现一次,各组人数最多相差 1。再次点击“生成分组”会重新分组,结果不保证与上次不同。

课堂任务

第一步只读名单,使用 QStringList 保存,显示有效人数。再加入空行过滤和重复检查,观察同名但学号不同的两条记录应怎样处理。

第二步实现抽签:先抽一人,再抽多人。让学生跟踪 takeAt 执行前后候选池的大小。

第三步实现分组。先按原顺序轮流分组,确认没有遗漏,再加入洗牌。把“随机顺序”和“完整分配”分开验证,便于找错。

第四步处理界面状态:名单编辑后禁用操作,应用成功后启用,名单重复时保留错误原因。

学生练习

  1. 增加“复制本轮抽签记录”按钮。
  2. 保存分组结果到文本文件,作为第8章的延伸任务。
  3. 增加“撤销上一次抽签”,明确如何把人员放回候选池,以及怎样修改历史记录。

验收用例

输入或操作 预期
空名单 显示提示,不允许开始
A 与前后带空格的 A 判断重复并指出行号
01 张三、02 张三 作为两位学生接受
4 人分两次各抽 2 人 四人各出现一次,随后不能继续抽
12 人,每组最多 5 人 3 组,每组 4 人
10 人,分成 3 组 人数为 4、3、3,顺序可变
3 人,要求分成 4 组 显示组数过多的提示
先抽签,再分组 分组仍包含全部名单
已生成结果后编辑名单 旧结果清空,重新应用前不能操作

自动化测试用固定种子得到可重复的随机序列,并对 1—100 人的两种分组方式检查总人数、唯一性和组间人数差。界面使用全局随机生成器,正常抽签不使用固定种子。