Files
Stu_scores_system/statistical_analysis.c
T
2025-07-12 23:33:14 +08:00

488 lines
14 KiB
C

/**
* @file statistical_analysis.c
* @brief 统计分析功能实现文件
* @note 实现各种统计分析功能
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "statistical_analysis.h"
#include "config.h"
#include "globals.h"
#include "auxiliary.h"
#include "stu.data.h"
/**
* @brief 显示课程统计信息
*/
void displayCourseStatistics()
{
clearScreen();
printHeader("课程统计信息");
if (studentCount == 0)
{
printWarning("暂无学生数据!");
pauseSystem();
return;
}
// 收集所有课程名称
char courses[MAX_STUDENTS * MAX_COURSES][MAX_COURSE_NAME_LENGTH];
int courseCount = 0;
for (int i = 0; i < studentCount; i++) {
for (int j = 0; j < students[i].courseCount; j++) {
bool exists = false;
for (int k = 0; k < courseCount; k++) {
if (strcmp(courses[k], students[i].courses[j]) == 0) {
exists = true;
break;
}
}
if (!exists) {
strcpy(courses[courseCount], students[i].courses[j]);
courseCount++;
}
}
}
if (courseCount == 0) {
printWarning("暂无课程数据!");
pauseSystem();
return;
}
printf("\n");
printf("%-20s %-8s %-8s %-8s %-8s %-8s\n",
"课程名称", "人数", "最高分", "最低分", "平均分", "及格率");
printSeparator();
for (int i = 0; i < courseCount; i++) {
CourseStats stats = calculateCourseStats(courses[i]);
printf("%-20s %-8d %-8.2f %-8.2f %-8.2f %-8.2f%%\n",
courses[i], stats.studentCount, stats.maxScore,
stats.minScore, stats.averageScore, stats.passRate);
}
pauseSystem();
}
/**
* @brief 计算课程统计信息
*/
CourseStats calculateCourseStats(const char* courseName) {
CourseStats stats = {0};
float scores[MAX_STUDENTS];
int count = 0;
// 收集该课程的所有分数
for (int i = 0; i < studentCount; i++) {
for (int j = 0; j < students[i].courseCount; j++) {
if (strcmp(students[i].courses[j], courseName) == 0) {
scores[count] = students[i].scores[j];
count++;
break;
}
}
}
if (count == 0) return stats;
stats.studentCount = count;
stats.maxScore = scores[0];
stats.minScore = scores[0];
stats.totalScore = 0;
int passCount = 0;
for (int i = 0; i < count; i++) {
if (scores[i] > stats.maxScore) stats.maxScore = scores[i];
if (scores[i] < stats.minScore) stats.minScore = scores[i];
stats.totalScore += scores[i];
if (scores[i] >= PASS_SCORE) passCount++;
}
stats.averageScore = stats.totalScore / count;
stats.passRate = (float)passCount / count * 100;
return stats;
}
/**
* @brief 显示分数分布
*/
void displayScoreDistribution() {
clearScreen();
printHeader("分数分布统计");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
ScoreDistribution dist = calculateScoreDistribution();
printf("\n分数段分布:\n");
printSeparator();
printf("90-100分: %d人 (%.2f%%)\n", dist.excellent,
(float)dist.excellent / studentCount * 100);
printf("80-89分: %d人 (%.2f%%)\n", dist.good,
(float)dist.good / studentCount * 100);
printf("70-79分: %d人 (%.2f%%)\n", dist.medium,
(float)dist.medium / studentCount * 100);
printf("60-69分: %d人 (%.2f%%)\n", dist.pass,
(float)dist.pass / studentCount * 100);
printf("0-59分: %d人 (%.2f%%)\n", dist.fail,
(float)dist.fail / studentCount * 100);
printf("\n总体统计:\n");
printf("总人数: %d\n", studentCount);
printf("及格人数: %d (%.2f%%)\n",
studentCount - dist.fail,
(float)(studentCount - dist.fail) / studentCount * 100);
printf("不及格人数: %d (%.2f%%)\n",
dist.fail, (float)dist.fail / studentCount * 100);
pauseSystem();
}
/**
* @brief 计算分数分布
*/
ScoreDistribution calculateScoreDistribution() {
ScoreDistribution dist = {0};
for (int i = 0; i < studentCount; i++) {
float avgScore = students[i].averageScore;
if (avgScore >= 90) {
dist.excellent++;
} else if (avgScore >= 80) {
dist.good++;
} else if (avgScore >= 70) {
dist.medium++;
} else if (avgScore >= 60) {
dist.pass++;
} else {
dist.fail++;
}
}
return dist;
}
/**
* @brief 显示学生排名
*/
void displayStudentRanking() {
clearScreen();
printHeader("学生排名");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
// 创建排名数组
StudentRank rankings[MAX_STUDENTS];
for (int i = 0; i < studentCount; i++) {
rankings[i].studentIndex = i;
rankings[i].averageScore = students[i].averageScore;
rankings[i].totalScore = students[i].totalScore;
}
// 按平均分排序(降序)
for (int i = 0; i < studentCount - 1; i++) {
for (int j = 0; j < studentCount - 1 - i; j++) {
if (rankings[j].averageScore < rankings[j + 1].averageScore) {
StudentRank temp = rankings[j];
rankings[j] = rankings[j + 1];
rankings[j + 1] = temp;
}
}
}
printf("\n");
// 调整中文表头的对齐格式,考虑中文字符的显示宽度
printf("%-5s %-10s %-12s %-8s %-8s\n",
"排名", "学号", "姓名", "总分", "平均分");
printf("========================================\n");
for (int i = 0; i < studentCount; i++) {
int idx = rankings[i].studentIndex;
printf("%-5d %-10s %-12s %-8.2f %-8.2f\n",
i + 1,
students[idx].studentID,
students[idx].name,
students[idx].totalScore,
students[idx].averageScore);
}
pauseSystem();
}
/**
* @brief 显示系统总体统计
*/
void displayOverallStatistics() {
clearScreen();
printHeader("系统总体统计");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
OverallStats stats = calculateOverallStats();
printf("\n学生信息统计:\n");
printSeparator();
printf("总学生数: %d\n", stats.totalStudents);
printf("男学生数: %d (%.2f%%)\n", stats.maleCount,
(float)stats.maleCount / stats.totalStudents * 100);
printf("女学生数: %d (%.2f%%)\n", stats.femaleCount,
(float)stats.femaleCount / stats.totalStudents * 100);
printf("平均年龄: %.1f岁\n", stats.averageAge);
printf("\n成绩统计:\n");
printSeparator();
printf("最高平均分: %.2f\n", stats.highestAverage);
printf("最低平均分: %.2f\n", stats.lowestAverage);
printf("全体平均分: %.2f\n", stats.overallAverageScore);
printf("标准差: %.2f\n", stats.standardDeviation);
printf("\n课程统计:\n");
printSeparator();
printf("总课程数: %d\n", stats.totalCourses);
printf("平均课程数/人: %.1f\n", stats.averageCoursesPerStudent);
pauseSystem();
}
/**
* @brief 计算系统总体统计
*/
OverallStats calculateOverallStats() {
OverallStats stats = {0};
if (studentCount == 0) return stats;
stats.totalStudents = studentCount;
float totalAge = 0;
float totalAverage = 0;
int totalCourseCount = 0;
// 收集所有课程名称
char courses[MAX_STUDENTS * MAX_COURSES][MAX_COURSE_NAME_LENGTH];
int uniqueCourseCount = 0;
stats.highestAverage = students[0].averageScore;
stats.lowestAverage = students[0].averageScore;
for (int i = 0; i < studentCount; i++) {
// 性别统计
if (students[i].gender == GENDER_MALE) {
stats.maleCount++;
} else if (students[i].gender == GENDER_FEMALE) {
stats.femaleCount++;
}
// 年龄统计
totalAge += students[i].age;
// 成绩统计
totalAverage += students[i].averageScore;
totalCourseCount += students[i].courseCount;
if (students[i].averageScore > stats.highestAverage) {
stats.highestAverage = students[i].averageScore;
}
if (students[i].averageScore < stats.lowestAverage) {
stats.lowestAverage = students[i].averageScore;
}
// 课程统计
for (int j = 0; j < students[i].courseCount; j++) {
bool exists = false;
for (int k = 0; k < uniqueCourseCount; k++) {
if (strcmp(courses[k], students[i].courses[j]) == 0) {
exists = true;
break;
}
}
if (!exists) {
strcpy(courses[uniqueCourseCount], students[i].courses[j]);
uniqueCourseCount++;
}
}
}
stats.averageAge = totalAge / studentCount;
stats.overallAverageScore = totalAverage / studentCount;
stats.totalCourses = uniqueCourseCount;
stats.averageCoursesPerStudent = (float)totalCourseCount / studentCount;
// 计算标准差
float variance = 0;
for (int i = 0; i < studentCount; i++) {
float diff = students[i].averageScore - stats.overallAverageScore;
variance += diff * diff;
}
variance /= studentCount;
stats.standardDeviation = sqrt(variance);
return stats;
}
/**
* @brief 查找最高分学生
*/
void findTopStudent() {
clearScreen();
printHeader("最高分学生");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
int topIndex = 0;
for (int i = 1; i < studentCount; i++) {
if (students[i].averageScore > students[topIndex].averageScore) {
topIndex = i;
}
}
printf("\n最高平均分学生:\n");
displayStudentInfo(&students[topIndex]);
pauseSystem();
}
/**
* @brief 查找最低分学生
*/
void findBottomStudent() {
clearScreen();
printHeader("最低分学生");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
int bottomIndex = 0;
for (int i = 1; i < studentCount; i++) {
if (students[i].averageScore < students[bottomIndex].averageScore) {
bottomIndex = i;
}
}
printf("\n最低平均分学生:\n");
displayStudentInfo(&students[bottomIndex]);
pauseSystem();
}
/**
* @brief 按课程查找最高分
*/
void findTopScoreInCourse() {
clearScreen();
printHeader("课程最高分查询");
if (studentCount == 0) {
printWarning("暂无学生数据!");
pauseSystem();
return;
}
char courseName[MAX_COURSE_NAME_LENGTH];
printf("\n");
safeInputString("请输入课程名称", courseName, MAX_COURSE_NAME_LENGTH);
float maxScore = -1;
int maxIndex = -1;
for (int i = 0; i < studentCount; i++) {
for (int j = 0; j < students[i].courseCount; j++) {
if (strcmp(students[i].courses[j], courseName) == 0) {
if (students[i].scores[j] > maxScore) {
maxScore = students[i].scores[j];
maxIndex = i;
}
}
}
}
if (maxIndex == -1) {
printError("未找到该课程!");
} else {
printf("\n课程 \"%s\" 最高分:\n", courseName);
printSeparator();
printf("学号: %s\n", students[maxIndex].studentID);
printf("姓名: %s\n", students[maxIndex].name);
printf("分数: %.2f\n", maxScore);
}
pauseSystem();
}
/**
* @brief 计算学生统计信息
*/
void calculateStudentStats(Student* student) {
if (student->courseCount == 0) {
student->totalScore = 0;
student->averageScore = 0;
return;
}
student->totalScore = 0;
for (int i = 0; i < student->courseCount; i++) {
student->totalScore += student->scores[i];
}
student->averageScore = student->totalScore / student->courseCount;
}
/**
* @brief 更新全局统计缓存
*/
void updateGlobalStats() {
if (studentCount == 0) {
overallAverageScore = 0;
highestScore = 0;
lowestScore = 0;
statsNeedUpdate = false;
return;
}
float total = 0;
highestScore = students[0].averageScore;
lowestScore = students[0].averageScore;
for (int i = 0; i < studentCount; i++) {
total += students[i].averageScore;
if (students[i].averageScore > highestScore) {
highestScore = students[i].averageScore;
}
if (students[i].averageScore < lowestScore) {
lowestScore = students[i].averageScore;
}
}
overallAverageScore = total / studentCount;
statsNeedUpdate = false;
}