排除缺席学号
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
FILE* fp;
void time()
{
time_t timep;
time(&timep);
struct tm* p = gmtime(&timep);
printf("%d/%d/%d", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
printf(" %d:%d:%d\n", (8 + p->tm_hour), p->tm_min, p->tm_sec);
fprintf(fp, "%d/%d/%d", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
fprintf(fp, " %d:%d:%d\n", (8 + p->tm_hour), p->tm_min, p->tm_sec);
}
void priarr(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%5d\t", a[i] + 1);fprintf(fp, "%-4d", a[i] + 1);
if ((i + 1) % 5 == 0)
{
printf("\n");fprintf(fp, "\n");
}
}
printf("\n\n");fprintf(fp, "\n\n");
}
void SortArr(int a[], int n)
{
int i, j, t;
for (i = 0; i < n - 1; i++)
for (j = i + 1; j < n; j++)
if (a[i] > a[j])
t = a[i], a[i] = a[j], a[j] = t;
}
void zhselect(int sum, int n)//zhselect(SUM, n);
{
int availableNums[sum];
for (int i = 0; i <= sum - 1; i++)//赋值1~sum-1
{
availableNums[i] = i + 1;
}
int selectedNums[n];
srand(time(NULL)); // 初始化随机数种子
for (int i = 0; i < n; i++)// 循环n次,随机选择n个数量的数字
{
// 从可用数字数组中选择一个随机数字
int index = rand() % sum;//这里的sum已经在上部分sum--循环中改变 此刻指数据库中数据的总数量。用于生成 0~sum-1 的随机数 。用于获得下标。
selectedNums[i] = availableNums[index];//availableNums[0~sum-1]; 得到的数均为已排除的数 。//可能重复
// 已选择的数字在数组中删除
for (int j = index; j < sum - 1; j++)
{
availableNums[j] = availableNums[j + 1];
}
sum--;
}
// 输出选择的数字
SortArr(selectedNums, n);
int q;
for (q = 0; q < n; q++)//【不知道哪里有问题,抽取的数字比预期大了1,我先直接减1】
{
selectedNums[q]--;
}
priarr(selectedNums, n);
}
void database(int abs[], int absents, int sum,int n )//database(abs, absents, SUM,n );
{
system("color 3E");
//共sum个学生sum个数最大的数也是sum
// 可用数字的范围1~sum
// 可用数字数组的初始化
int availableNums[sum];
for (int i = 0; i <= sum - 1; i++)//赋值1~sum-1
{
availableNums[i] = i + 1;
}
// 从1~sum 中删除要排除的数字
for (int i = 0; i < absents; i++)
{
int excludeNum = abs[i];//逐个排除
for (int j = 0; j <= sum - 1; j++) //扫描原始数据 1~sum
{
if (availableNums[j] == excludeNum)//1~sum 中删除要排除的数
{
// 已找到要排除的数字,在数组中删除
for (int k = j; k < sum - 1; k++)//后面的数整体向左移
{
availableNums[k] = availableNums[k + 1];//预删除的位置被后面的数左移占用
}
sum--;//数组中减少一个数
break;//跳出上上一个for再次进入第一个循环
}
}
}
//此上是造好的数据库
//从剩余数中抽取它们的下标。这就叫造数据库
int selectedNums[n];
srand(time(NULL)); // 初始化随机数种子
for (int i = 0; i < n; i++)// 循环n次,随机选择n个数量的数字
{
// 从可用数字数组中选择一个随机数字
int index = rand() % sum;//这里的sum已经在上部分sum--循环中改变 此刻指数据库中数据的总数量。用于生成 0~sum-1 的随机数 。用于获得下标。
selectedNums[i] = availableNums[index];//availableNums[0~sum-1]; 得到的数均为已排除的数 。//可能重复
// 已选择的数字在数组中删除
for (int j = index; j < sum - 1; j++)
{
availableNums[j] = availableNums[j + 1];
}
sum--;
}
// 输出选择的数字
SortArr(selectedNums, n);
int q;
for (q = 0; q < n; q++)//【不知道哪里有问题,抽取的数字比预期大了1,我先直接减1】
{
selectedNums[q]--;
}
priarr(selectedNums, n);
}
int main()
{
fp = fopen("date.dat", "a+");
system("color 3C");
system("title 课堂简单抽签系统");
time();
printf("\n");
int SUM,F,sum, absents=0, n, i;
SUM = sum;
printf("请输入班级总人数:"); scanf("%d", &SUM);fprintf(fp, "班级总人数:%d\n", SUM);
printf("缺席人个数:"); scanf("%d", &absents);fprintf(fp, "缺席人个数:%d\n", absents);
if (absents> 0)
{
int abs[absents] = {0};
printf("请从小至大输入缺席人学号:"); fprintf(fp, "缺席人学号:");
for (i = 0; i < absents; i++) {scanf("%d", &abs[i]);fprintf(fp, "%d ", abs[i]);}fprintf(fp, "\n\n");
printf("请输入抽取人数:"); scanf("%d", &n);fprintf(fp, "抽取人数:%d\n", n);
do {
F=SUM - absents - n;
while (F<0) { printf("所抽取多于出席人数,请重新输入抽取人数:"); scanf("%d", &n);F=SUM - absents - n;}
system("cls"); time(); system("color 3E");printf("\n");
printf("幸运学号:\n\n");fprintf(fp, "幸运学号:\n");
database(abs, absents, SUM,n );
printf("请输入抽取人数:");
scanf("%d", &n); fprintf(fp, "抽取人数:%d\n", n);
} while (n != 0);
}
if(absents == 0)
{
fprintf(fp, "\n\n");
printf("请输入抽取人数:"); scanf("%d", &n);fprintf(fp, "抽取人数:%d\n", n);
do {
F=SUM-n;
while(F<0){ printf("所抽取多于出席人数,请重新输入抽取人数:"); scanf("%d", &n);F=SUM-n;}
system("cls"); time(); system("color 3E");printf("\n");
printf("幸运学号:\n\n");fprintf(fp, "幸运学号:\n");
zhselect(SUM, n);
printf("请输入抽取人数:");
scanf("%d", &n);fprintf(fp, "抽取人数:%d\n", n);
} while (n != 0);
}
fclose(fp);
return 0;
}