大家好,我是老刘,数学学科作为一门基础学科,新课标要求注重活动化、游戏化、生活化的学习设计;以前的【编程与数学】序列,我们充分利用图形化编程的可视化特点,将数学融合起来,作为一种创新的学习方式,可以使得数学学科的教学更加生动有趣,形象直观;
今天老刘分享C++编程与数学融合学习课程纲要,探索如何将数学知识与C++编程紧密结合?目标是先理解数学概念,再编程实现,通过完整项目整合知识点,鼓励学生结对编程,培养团队协作能力。
一、课程整体设计思路
本课程以人教版八年级下册数学知识为主线,通过C++编程实现数学概念的验证、应用和拓展,培养学生的计算思维、逻辑推理能力和问题解决能力。课程采用"数学概念→编程实现→实际应用"的三步教学模式。
二、各单元详细知识点对应表
第一单元:二次根式(4课时)
数学知识点:
二次根式的概念和性质
二次根式的乘除运算
二次根式的加减运算
最简二次根式和同类二次根式
二次根式的化简与运算
C++知识点:
编程实践:
// 二次根式计算器#include<iostream>#include<cmath>#include<iomanip>using namespace std;// 判断一个数是否为完全平方数boolisPerfectSquare(int n){ int root = sqrt(n); return root * root == n;}// 化简二次根式voidsimplifySqrt(int n){ if(n < 0) { cout << "负数没有实数平方根" << endl; return; } if(isPerfectSquare(n)) { cout << "√" << n << " = " << sqrt(n) << endl; return; } // 寻找最大平方因子 int factor = 1; for(int i = sqrt(n); i >= 2; i--) { if(n % (i*i) == 0) { factor = i; break; } } int remaining = n / (factor*factor); if(factor == 1) { cout << "√" << n << " 已是最简形式 ≈ " << sqrt(n) << endl; } else { cout << "√" << n << " = " << factor << "√" << remaining; cout << " ≈ " << factor * sqrt(remaining) << endl; }}intmain(){ cout << "=== 二次根式计算器 ===" << endl; // 1. 计算平方根 cout << "\n1. 计算平方根" << endl; for(int i = 2; i <= 20; i++) { cout << "√" << i << " = " << sqrt(i); if(isPerfectSquare(i)) { cout << " (有理数)"; } else { cout << " (无理数)"; } cout << endl; } // 2. 化简二次根式 cout << "\n2. 化简二次根式" << endl; int numbers[] = {8, 12, 18, 20, 24, 27, 32, 45, 50, 72}; for(int num : numbers) { simplifySqrt(num); } // 3. 二次根式运算 cout << "\n3. 二次根式运算" << endl; double a, b; cout << "输入两个数a和b:"; cin >> a >> b; cout << fixed << setprecision(3); cout << "√a + √b = " << sqrt(a) + sqrt(b) << endl; cout << "√a - √b = " << sqrt(a) - sqrt(b) << endl; cout << "√a × √b = " << sqrt(a) * sqrt(b) << endl; if(b != 0) { cout << "√a ÷ √b = " << sqrt(a) / sqrt(b) << endl; } // 4. 同类二次根式判断 cout << "\n4. 同类二次根式判断" << endl; cout << "判断√8、√18、√32是否为同类二次根式:" << endl; // 化简并比较 simplifySqrt(8); simplifySqrt(18); simplifySqrt(32); // 判断方法:化简后根号内的数是否相同 cout << "化简后根号内的数都是2,所以它们是同类二次根式" << endl; return 0;}
课后练习1:
编写程序,输入一个正整数n,输出n以内的所有完全平方数
编写程序,计算两个二次根式的和,并化简结果
编写程序,判断两个二次根式是否为同类二次根式
第二单元:勾股定理(3课时)
数学知识点:
勾股定理及其证明
勾股定理的逆定理
勾股定理的应用
勾股数
C++知识点:
函数定义与调用
布尔类型和逻辑运算
三重循环(用于寻找勾股数)
结构体的使用
// 勾股定理应用#include<iostream>#include<cmath>#include<iomanip>#include<vector>#include<algorithm>using namespace std;// 定义三角形结构体struct Triangle { double a, b, c; bool isRight; // 是否为直角三角形};// 检查是否为直角三角形boolisRightTriangle(double a, double b, double c){ // 对边进行排序,c为最长边 vector<double> sides = {a, b, c}; sort(sides.begin(), sides.end()); // 检查勾股定理 return fabs(pow(sides[0], 2) + pow(sides[1], 2) - pow(sides[2], 2)) < 1e-6;}// 寻找勾股数voidfindPythagoreanTriples(int limit){ cout << "\n勾股数(a² + b² = c²,a < b < c ≤ " << limit << "):" << endl; int count = 0; for(int c = 1; c <= limit; c++) { for(int b = 1; b < c; b++) { for(int a = 1; a < b; a++) { if(a*a + b*b == c*c) { cout << ++count << ". (" << a << ", " << b << ", " << c << ")"; // 检查是否为互质(最大公约数为1) int x = a, y = b, z = c; while(y != 0) { int temp = y; y = x % y; x = temp; } while(z != 0) { int temp = z; z = x % z; x = temp; } if(x == 1) cout << " [互质]"; cout << endl; } } } } cout << "共找到 " << count << " 组勾股数" << endl;}intmain(){ cout << "=== 勾股定理应用 ===" << endl; // 1. 判断三角形类型 cout << "\n1. 判断三角形类型" << endl; Triangle t; cout << "输入三角形三边长:"; cin >> t.a >> t.b >> t.c; t.isRight = isRightTriangle(t.a, t.b, t.c); if(t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a) { cout << "可以构成三角形" << endl; if(t.isRight) { cout << "这是直角三角形" << endl; // 找出直角边和斜边 vector<double> sides = {t.a, t.b, t.c}; sort(sides.begin(), sides.end()); cout << "直角边:" << sides[0] << " 和 " << sides[1] << endl; cout << "斜边:" << sides[2] << endl; cout << "勾股定理验证:" << sides[0] << "² + " << sides[1] << "² = " << sides[0]*sides[0] + sides[1]*sides[1] << " = " << sides[2] << "²" << endl; } else { cout << "这不是直角三角形" << endl; } } else { cout << "无法构成三角形" << endl; } // 2. 应用问题:测量问题 cout << "\n2. 应用:测量问题" << endl; cout << "问题:从电线杆离地面8米处向地面拉一条10米长的缆绳,求缆绳固定点与电线杆底部的距离" << endl; double height = 8, rope = 10; double distance = sqrt(pow(rope, 2) - pow(height, 2)); cout << "缆绳固定点与电线杆底部的距离:" << distance << " 米" << endl; // 3. 寻找勾股数 cout << "\n3. 寻找勾股数" << endl; int limit; cout << "输入上限:"; cin >> limit; findPythagoreanTriples(limit); // 4. 勾股定理逆定理验证 cout << "\n4. 勾股定理逆定理验证" << endl; cout << "输入三个正整数,判断它们是否能构成直角三角形:"; int x, y, z; cin >> x >> y >> z; if(isRightTriangle(x, y, z)) { cout << "可以构成直角三角形" << endl; } else { cout << "不能构成直角三角形" << endl; } return 0;}
课后练习2:
编写程序,输入直角三角形的两条边,计算第三条边
编写程序,生成所有满足a+b+c=100的直角三角形三边长
编写程序,验证勾股定理的多种证明方法(如赵爽弦图)
第三单元:平行四边形(4课时)
数学知识点:
平行四边形的性质
平行四边形的判定
矩形、菱形、正方形的性质和判定
梯形和等腰梯形的性质
中位线定理
C++知识点:
编程实践:
// 四边形性质判断与计算#include<iostream>#include<cmath>#include<iomanip>#include<vector>#include<algorithm>using namespace std;// 定义点结构体struct Point { double x, y;};// 定义四边形类class Quadrilateral {private: Point A, B, C, D;public: Quadrilateral(Point a, Point b, Point c, Point d) : A(a), B(b), C(c), D(d) {} // 计算两点间距离 doubledistance(Point p1, Point p2){ return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)); } // 计算向量 pair<double, double> vector2D(Point from, Point to){ return make_pair(to.x - from.x, to.y - from.y); } // 计算斜率 doubleslope(Point p1, Point p2){ if(fabs(p1.x - p2.x) < 1e-6) return INFINITY; return (p2.y - p1.y) / (p2.x - p1.x); } // 判断两条线是否平行(考虑浮点误差) boolisParallel(pair<double, double> v1, pair<double, double> v2){ // 向量平行:v1 = k * v2 if(fabs(v2.first) < 1e-6 && fabs(v2.second) < 1e-6) return false; if(fabs(v2.first) > 1e-6) { double k = v1.first / v2.first; return fabs(v1.second - k * v2.second) < 1e-6; } else { double k = v1.second / v2.second; return fabs(v1.first - k * v2.first) < 1e-6; } } // 判断是否为平行四边形 boolisParallelogram(){ pair<double, double> AB = vector2D(A, B); pair<double, double> BC = vector2D(B, C); pair<double, double> CD = vector2D(C, D); pair<double, double> DA = vector2D(D, A); // 对边平行 return isParallel(AB, CD) && isParallel(BC, DA); } // 判断是否为矩形 boolisRectangle(){ if(!isParallelogram()) return false; // 检查是否有直角 pair<double, double> AB = vector2D(A, B); pair<double, double> BC = vector2D(B, C); // 点积为0表示垂直 double dotProduct = AB.first * BC.first + AB.second * BC.second; return fabs(dotProduct) < 1e-6; } // 判断是否为菱形 boolisRhombus(){ if(!isParallelogram()) return false; // 检查四条边是否相等 double AB = distance(A, B); double BC = distance(B, C); double CD = distance(C, D); double DA = distance(D, A); return fabs(AB - BC) < 1e-6 && fabs(BC - CD) < 1e-6 && fabs(CD - DA) < 1e-6; } // 判断是否为正方形 boolisSquare(){ return isRectangle() && isRhombus(); } // 计算周长 doubleperimeter(){ return distance(A, B) + distance(B, C) + distance(C, D) + distance(D, A); } // 计算面积(使用鞋带公式) doublearea(){ return fabs( A.x*B.y + B.x*C.y + C.x*D.y + D.x*A.y - A.y*B.x - B.y*C.x - C.y*D.x - D.y*A.x ) / 2.0; } // 显示四边形信息 voiddisplay(){ cout << fixed << setprecision(2); cout << "四边形顶点坐标:" << endl; cout << "A(" << A.x << ", " << A.y << ")" << endl; cout << "B(" << B.x << ", " << B.y << ")" << endl; cout << "C(" << C.x << ", " << C.y << ")" << endl; cout << "D(" << D.x << ", " << D.y << ")" << endl; cout << "\n四边形性质:" << endl; if(isParallelogram()) { cout << "- 是平行四边形" << endl; if(isRectangle()) cout << "- 是矩形" << endl; if(isRhombus()) cout << "- 是菱形" << endl; if(isSquare()) cout << "- 是正方形" << endl; } else { cout << "- 不是平行四边形" << endl; } cout << "\n几何属性:" << endl; cout << "周长:" << perimeter() << endl; cout << "面积:" << area() << endl; }};intmain(){ cout << "=== 四边形性质判断与计算 ===" << endl; // 示例1:平行四边形 cout << "\n示例1:平行四边形" << endl; { Point A = {0, 0}; Point B = {4, 0}; Point C = {5, 3}; Point D = {1, 3}; Quadrilateral q1(A, B, C, D); q1.display(); } // 示例2:矩形 cout << "\n示例2:矩形" << endl; { Point A = {0, 0}; Point B = {4, 0}; Point C = {4, 3}; Point D = {0, 3}; Quadrilateral q2(A, B, C, D); q2.display(); } // 示例3:正方形 cout << "\n示例3:正方形" << endl; { Point A = {0, 0}; Point B = {3, 0}; Point C = {3, 3}; Point D = {0, 3}; Quadrilateral q3(A, B, C, D); q3.display(); } // 用户输入四边形 cout << "\n请输入四边形四个顶点的坐标:" << endl; Point A, B, C, D; cout << "A点(x y): "; cin >> A.x >> A.y; cout << "B点(x y): "; cin >> B.x >> B.y; cout << "C点(x y): "; cin >> C.x >> C.y; cout << "D点(x y): "; cin >> D.x >> D.y; Quadrilateral userQuad(A, B, C, D); userQuad.display(); // 梯形判断 cout << "\n判断是否为梯形:" << endl; // 检查是否有一组对边平行 pair<double, double> AB = userQuad.vector2D(A, B); pair<double, double> CD = userQuad.vector2D(C, D); pair<double, double> BC = userQuad.vector2D(B, C); pair<double, double> DA = userQuad.vector2D(D, A); if(userQuad.isParallel(AB, CD) || userQuad.isParallel(BC, DA)) { cout << "是梯形" << endl; } else { cout << "不是梯形" << endl; } return 0;}
课后练习3:
编写程序,输入平行四边形的底和高,计算面积和周长
编写程序,判断四边形是否为等腰梯形
编写程序,计算梯形的中位线长度
第四单元:一次函数(5课时)
数学知识点:
函数的概念
一次函数的图像和性质
用待定系数法确定一次函数表达式
一次函数与方程、不等式的关系
一次函数的应用
C++知识点:
函数的定义与调用
数组和向量
文件操作
图形绘制(简单字符图形)
算法的复杂度
编程实践:
// 一次函数分析工具#include<iostream>#include<cmath>#include<iomanip>#include<vector>#include<fstream>#include<algorithm>using namespace std;// 一次函数类class LinearFunction {private: double k; // 斜率 double b; // 截距public: LinearFunction(double k_val = 1, double b_val = 0) : k(k_val), b(b_val) {} // 计算函数值 doublevalue(double x){ return k * x + b; } // 求零点(与x轴交点) doublezero(){ if(k == 0) { if(b == 0) return 0; // 无穷多解 return NAN; // 无解 } return -b / k; } // 求与y轴交点 doubleyIntercept(){ return b; } // 判断增减性 string monotonicity(){ if(k > 0) return "递增"; if(k < 0) return "递减"; return "常数"; } // 求两条直线的交点 pair<double, double> intersection(LinearFunction other){ if(fabs(k - other.k) < 1e-6) { // 平行或重合 if(fabs(b - other.b) < 1e-6) { return make_pair(NAN, NAN); // 重合,无穷多交点 } return make_pair(INFINITY, INFINITY); // 平行,无交点 } double x = (other.b - b) / (k - other.k); double y = value(x); return make_pair(x, y); } // 显示函数信息 voiddisplay(){ cout << "函数:y = "; if(k != 1 && k != -1) { if(k != 0) cout << k; } else if(k == -1) { cout << "-"; } if(k != 0) cout << "x"; if(b > 0) { cout << " + " << b; } else if(b < 0) { cout << " - " << -b; } else if(k == 0) { cout << b; } cout << endl; cout << "斜率k = " << k << endl; cout << "截距b = " << b << endl; cout << "与y轴交点:(0, " << yIntercept() << ")" << endl; double zeroPoint = zero(); if(!isnan(zeroPoint)) { cout << "与x轴交点:(" << zeroPoint << ", 0)" << endl; } else { cout << "与x轴无交点" << endl; } cout << "增减性:" << monotonicity() << endl; } // 绘制函数图像(简单字符图形) voidplot(int width = 50, int height = 25){ vector<vector<char>> grid(height, vector<char>(width, ' ')); // 绘制坐标轴 int midX = width / 2; int midY = height / 2; // x轴 for(int x = 0; x < width; x++) { grid[midY][x] = '-'; } // y轴 for(int y = 0; y < height; y++) { grid[y][midX] = '|'; } // 原点 grid[midY][midX] = '+'; // 绘制函数图像 double scaleX = 10.0 / (width/2); // x轴的缩放比例 double scaleY = 10.0 / (height/2); // y轴的缩放比例 for(int i = 0; i < width; i++) { double x = (i - midX) * scaleX; double y = value(x); int y_pixel = midY - int(y / scaleY + 0.5); if(y_pixel >= 0 && y_pixel < height) { grid[y_pixel][i] = '*'; } } // 输出图像 cout << "\n函数图像(简易版):" << endl; for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { cout << grid[y][x]; } cout << endl; } } // 求解不等式 kx + b > 0 voidsolveInequality(){ cout << "\n解不等式 " << k << "x "; if(b >= 0) cout << "+ " << b; else cout << "- " << -b; cout << " > 0" << endl; double zeroPoint = zero(); if(isnan(zeroPoint)) { if(b > 0) cout << "解集为全体实数" << endl; else cout << "无解" << endl; } else { if(k > 0) { cout << "x > " << zeroPoint << endl; } else if(k < 0) { cout << "x < " << zeroPoint << endl; } } }};// 通过两点确定一次函数LinearFunction linearFunctionFromPoints(double x1, double y1, double x2, double y2){ if(fabs(x1 - x2) < 1e-6) { cout << "两点x坐标相同,不是函数" << endl; return LinearFunction(NAN, NAN); } double k = (y2 - y1) / (x2 - x1); double b = y1 - k * x1; return LinearFunction(k, b);}// 最小二乘法拟合一次函数LinearFunction linearRegression(const vector<double>& x, const vector<double>& y){ int n = x.size(); double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; for(int i = 0; i < n; i++) { sumX += x[i]; sumY += y[i]; sumXY += x[i] * y[i]; sumX2 += x[i] * x[i]; } double k = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX); double b = (sumY - k * sumX) / n; return LinearFunction(k, b);}intmain(){ cout << "=== 一次函数分析工具 ===" << endl; // 1. 创建一次函数 cout << "\n1. 创建一次函数" << endl; double k, b; cout << "输入斜率k和截距b:"; cin >> k >> b; LinearFunction f1(k, b); f1.display(); // 2. 计算函数值 cout << "\n2. 计算函数值" << endl; double x; cout << "输入x值:"; cin >> x; cout << "f(" << x << ") = " << f1.value(x) << endl; // 3. 绘制函数图像 cout << "\n3. 绘制函数图像" << endl; f1.plot(); // 4. 解不等式 f1.solveInequality(); // 5. 两点确定一次函数 cout << "\n5. 通过两点确定一次函数" << endl; double x1, y1, x2, y2; cout << "输入点1坐标(x y):"; cin >> x1 >> y1; cout << "输入点2坐标(x y):"; cin >> x2 >> y2; LinearFunction f2 = linearFunctionFromPoints(x1, y1, x2, y2); f2.display(); // 6. 求两条直线的交点 cout << "\n6. 求两条直线的交点" << endl; pair<double, double> intersection = f1.intersection(f2); if(isinf(intersection.first)) { cout << "两条直线平行,无交点" << endl; } else if(isnan(intersection.first)) { cout << "两条直线重合,有无穷多交点" << endl; } else { cout << "交点坐标:(" << intersection.first << ", " << intersection.second << ")" << endl; } // 7. 线性回归 cout << "\n7. 线性回归(最小二乘法)" << endl; vector<double> xs = {1, 2, 3, 4, 5}; vector<double> ys = {2, 4, 5, 4, 5}; cout << "样本数据:" << endl; for(int i = 0; i < xs.size(); i++) { cout << "(" << xs[i] << ", " << ys[i] << ")" << endl; } LinearFunction regression = linearRegression(xs, ys); cout << "\n回归直线:"; regression.display(); // 8. 应用问题 cout << "\n8. 应用问题:手机套餐选择" << endl; cout << "套餐A:月租30元,通话0.2元/分钟" << endl; cout << "套餐B:月租50元,通话0.1元/分钟" << endl; LinearFunction planA(0.2, 30); // y = 0.2x + 30 LinearFunction planB(0.1, 50); // y = 0.1x + 50 // 计算平衡点 pair<double, double> balance = planA.intersection(planB); double balanceMinutes = balance.first; double balanceCost = balance.second; cout << "平衡点:" << balanceMinutes << "分钟,费用" << balanceCost << "元" << endl; cout << "建议:" << endl; cout << "- 如果每月通话少于" << balanceMinutes << "分钟,选择套餐A更划算" << endl; cout << "- 如果每月通话多于" << balanceMinutes << "分钟,选择套餐B更划算" << endl; return 0;}
课后练习4:
编写程序,输入一次函数和x的范围,输出函数值表
编写程序,实现一次函数图像的平移和伸缩变换
编写程序,解决一次函数与二元一次方程组的关系问题
第五单元:数据的分析(3课时)
数学知识点:
平均数、加权平均数
中位数、众数
方差、标准差
数据分析的应用
C++知识点:
数组和向量的高级操作
排序算法
统计计算
文件操作
数据可视化
编程实践:
// 数据分析系统#include<iostream>#include<fstream>#include<vector>#include<algorithm>#include<cmath>#include<iomanip>#include<map>#include<limits>using namespace std;class DataAnalyzer {private: vector<double> data; string dataSource;public: DataAnalyzer() {} // 从文件加载数据 boolloadFromFile(const string& filename){ ifstream file(filename); if(!file.is_open()) { cout << "无法打开文件:" << filename << endl; return false; } data.clear(); double value; while(file >> value) { data.push_back(value); } file.close(); dataSource = filename; return true; } // 手动输入数据 voidinputData(){ data.clear(); int n; cout << "输入数据个数:"; cin >> n; cout << "输入" << n << "个数据:" << endl; for(int i = 0; i < n; i++) { double value; cin >> value; data.push_back(value); } dataSource = "手动输入"; } // 生成随机数据 voidgenerateRandomData(int count, double minVal, double maxVal){ data.clear(); srand(time(0)); for(int i = 0; i < count; i++) { double value = minVal + (maxVal - minVal) * (rand() / double(RAND_MAX)); data.push_back(value); } dataSource = "随机生成"; } // 计算基本统计量 voidcalculateBasicStats(){ if(data.empty()) { cout << "没有数据" << endl; return; } sort(data.begin(), data.end()); double sum = 0; double minVal = data[0]; double maxVal = data.back(); for(double val : data) { sum += val; } double mean = sum / data.size(); double median; if(data.size() % 2 == 1) { median = data[data.size() / 2]; } else { median = (data[data.size() / 2 - 1] + data[data.size() / 2]) / 2.0; } // 众数 map<double, int> freq; for(double val : data) { freq[val]++; } double mode = data[0]; int maxFreq = 0; for(auto& pair : freq) { if(pair.second > maxFreq) { maxFreq = pair.second; mode = pair.first; } } // 方差和标准差 double variance = 0; for(double val : data) { variance += pow(val - mean, 2); } variance /= data.size(); double stddev = sqrt(variance); // 四分位数 double q1, q3; int n = data.size(); if(n % 2 == 0) { q1 = data[n/4]; q3 = data[3*n/4]; } else { q1 = data[(n-1)/4]; q3 = data[3*(n-1)/4]; } double IQR = q3 - q1; // 四分位距 // 输出结果 cout << fixed << setprecision(3); cout << "=== 基本统计量 ===" << endl; cout << "数据来源:" << dataSource << endl; cout << "数据个数:" << data.size() << endl; cout << "最小值: " << minVal << endl; cout << "最大值: " << maxVal << endl; cout << "极差: " << maxVal - minVal << endl; cout << "平均数: " << mean << endl; cout << "中位数: " << median << endl; cout << "众数: " << mode << "(出现" << maxFreq << "次)" << endl; cout << "方差: " << variance << endl; cout << "标准差: " << stddev << endl; cout << "第一四分位数(Q1):" << q1 << endl; cout << "第三四分位数(Q3):" << q3 << endl; cout << "四分位距(IQR): " << IQR << endl; // 异常值检测 double lowerBound = q1 - 1.5 * IQR; double upperBound = q3 + 1.5 * IQR; vector<double> outliers; for(double val : data) { if(val < lowerBound || val > upperBound) { outliers.push_back(val); } } if(!outliers.empty()) { cout << "\n异常值检测:" << endl; cout << "正常值范围:[" << lowerBound << ", " << upperBound << "]" << endl; cout << "发现" << outliers.size() << "个异常值:" << endl; for(double val : outliers) { cout << val << " "; } cout << endl; } } // 计算加权平均数 doubleweightedMean(const vector<double>& weights){ if(data.size() != weights.size()) { cout << "数据个数与权重个数不匹配" << endl; return NAN; } double weightedSum = 0; double weightSum = 0; for(int i = 0; i < data.size(); i++) { weightedSum += data[i] * weights[i]; weightSum += weights[i]; } return weightedSum / weightSum; } // 绘制直方图 voiddrawHistogram(int bins = 10){ if(data.empty()) return; double minVal = *min_element(data.begin(), data.end()); double maxVal = *max_element(data.begin(), data.end()); double range = maxVal - minVal; double binWidth = range / bins; vector<int> freq(bins, 0); for(double val : data) { int binIndex = min(int((val - minVal) / binWidth), bins - 1); freq[binIndex]++; } int maxFreq = *max_element(freq.begin(), freq.end()); int maxStars = 50; cout << "\n=== 直方图 ===" << endl; for(int i = 0; i < bins; i++) { double lower = minVal + i * binWidth; double upper = lower + binWidth; cout << "[" << setw(6) << lower << ", " << setw(6) << upper << "): "; int stars = (maxFreq > 0) ? (freq[i] * maxStars / maxFreq) : 0; for(int j = 0; j < stars; j++) { cout << "*"; } cout << " (" << freq[i] << ")" << endl; } } // 绘制箱线图(字符版) voiddrawBoxPlot(){ if(data.empty()) return; sort(data.begin(), data.end()); int n = data.size(); double q1 = data[n/4]; double median = (n % 2 == 1) ? data[n/2] : (data[n/2-1] + data[n/2]) / 2; double q3 = data[3*n/4]; double IQR = q3 - q1; double lowerBound = q1 - 1.5 * IQR; double upperBound = q3 + 1.5 * IQR; // 找出正常值范围内的最小值和最大值 double lowerWhisker = data.back(); double upperWhisker = data[0]; for(double val : data) { if(val >= lowerBound && val <= upperBound) { lowerWhisker = min(lowerWhisker, val); upperWhisker = max(upperWhisker, val); } } // 创建箱线图 const int width = 60; vector<char> line(width, ' '); // 刻度 double minVal = data[0]; double maxVal = data.back(); double scale = (maxVal - minVal) / (width - 1); auto valueToPosition = [&](double value) -> int { return int((value - minVal) / scale); }; // 绘制箱线图 line[valueToPosition(minVal)] = '|'; line[valueToPosition(maxVal)] = '|'; int posLowerWhisker = valueToPosition(lowerWhisker); int posQ1 = valueToPosition(q1); int posMedian = valueToPosition(median); int posQ3 = valueToPosition(q3); int posUpperWhisker = valueToPosition(upperWhisker); // 绘制箱体 for(int i = posQ1; i <= posQ3; i++) { line[i] = '='; } // 绘制中位数线 line[posMedian] = '|'; // 绘制须线 for(int i = posLowerWhisker; i <= posQ1; i++) { line[i] = '-'; } for(int i = posQ3; i <= posUpperWhisker; i++) { line[i] = '-'; } // 标记异常值 for(double val : data) { if(val < lowerBound || val > upperBound) { int pos = valueToPosition(val); if(pos >= 0 && pos < width) { line[pos] = '*'; } } } // 输出箱线图 cout << "\n=== 箱线图 ===" << endl; for(int i = 0; i < width; i++) { cout << line[i]; } cout << endl; // 输出刻度 cout << setw(valueToPosition(minVal)) << minVal; cout << setw(valueToPosition(median) - valueToPosition(minVal)) << median; cout << setw(valueToPosition(maxVal) - valueToPosition(median)) << maxVal << endl; cout << "\n图例:- 须线,= 箱体,| 中位数,* 异常值" << endl; } // 保存分析结果到文件 voidsaveResults(const string& filename){ ofstream file(filename); if(!file.is_open()) { cout << "无法创建文件:" << filename << endl; return; } file << fixed << setprecision(3); file << "数据分析报告" << endl; file << "数据来源:" << dataSource << endl; file << "数据个数:" << data.size() << endl; // 保存数据 file << "\n原始数据:" << endl; for(double val : data) { file << val << " "; } file << endl; // 计算并保存统计量 sort(data.begin(), data.end()); double sum = 0; for(double val : data) sum += val; double mean = sum / data.size(); double variance = 0; for(double val : data) { variance += pow(val - mean, 2); } variance /= data.size(); file << "\n统计量:" << endl; file << "最小值:" << data[0] << endl; file << "最大值:" << data.back() << endl; file << "平均数:" << mean << endl; file << "方差:" << variance << endl; file << "标准差:" << sqrt(variance) << endl; file.close(); cout << "分析结果已保存到:" << filename << endl; }};intmain(){ DataAnalyzer analyzer; int choice; do { cout << "\n=== 数据分析系统 ===" << endl; cout << "1. 从文件加载数据" << endl; cout << "2. 手动输入数据" << endl; cout << "3. 生成随机数据" << endl; cout << "4. 计算基本统计量" << endl; cout << "5. 绘制直方图" << endl; cout << "6. 绘制箱线图" << endl; cout << "7. 保存分析结果" << endl; cout << "8. 加权平均数计算" << endl; cout << "0. 退出" << endl; cout << "请选择:"; cin >> choice; switch(choice) { case 1: { string filename; cout << "输入文件名:"; cin >> filename; analyzer.loadFromFile(filename); break; } case 2: analyzer.inputData(); break; case 3: { int count; double minVal, maxVal; cout << "输入数据个数:"; cin >> count; cout << "输入最小值:"; cin >> minVal; cout << "输入最大值:"; cin >> maxVal; analyzer.generateRandomData(count, minVal, maxVal); break; } case 4: analyzer.calculateBasicStats(); break; case 5: analyzer.drawHistogram(); break; case 6: analyzer.drawBoxPlot(); break; case 7: { string filename; cout << "输入保存文件名:"; cin >> filename; analyzer.saveResults(filename); break; } case 8: { int n; cout << "输入权重个数:"; cin >> n; vector<double> weights(n); cout << "输入" << n << "个权重:" << endl; for(int i = 0; i < n; i++) { cin >> weights[i]; } double result = analyzer.weightedMean(weights); if(!isnan(result)) { cout << "加权平均数:" << result << endl; } break; } case 0: cout << "退出系统" << endl; break; default: cout << "无效选择" << endl; } } while(choice != 0); return 0;}
课后练习5:
编写程序,计算班级学生成绩的方差和标准差,并分析成绩分布
编写程序,实现数据的归一化处理(将数据缩放到0-1范围)
编写程序,比较两组数据的差异(如t检验的简化版)
三、综合复习与期末项目
综合复习要点:
代数部分:二次根式的运算、勾股定理的应用
几何部分:四边形的性质与判定、空间想象能力
函数部分:一次函数的性质与应用、函数图像的绘制
统计部分:数据的收集与分析、统计量的计算
C++编程核心:类与对象、算法设计、文件操作、数据可视化
期末项目:学校成绩管理系统增强版
项目要求:
使用面向对象编程,设计学生、班级、课程等类
从文件读取学生信息和各科成绩
实现以下功能:
数据可视化:使用字符或简单图形展示分析结果
数据持久化:将分析结果保存到文件
软件:Code::Blocks / Dev-C++ / VS Code
教材:人教版六年级下册数学教材
参考资料:C++入门教程、数学与编程结合的案例集
在线资源:在线编程练习平台、数学可视化工具
推荐阅读
编程与数学||C++编程与七年级下册数学融合学习纲要
编程与数学||C++编程与小学数学融合学习纲要
开卷有益,原创不易,且行且努力。公众号每一篇文章都经过我们的精选和编写、用心去完成的,大家转载时请注明来源!