1、递归实现N的阶乘
c复制
#include <cstdio> // 包含标准输入输出库
// 计算n的阶乘
int total = 0; // 定义全局变量total用于存储阶乘结果
// 递归函数计算阶乘
int fac(int a){
// 如果输入的数小于0,输出错误信息
if (a < 0){
printf("%d < 0,error!",a);
}
// 如果输入的数是0或1,阶乘结果为1
else if (a == 0 || a==1){
total = 1;
}
// 否则,递归调用fac函数计算阶乘
else{
total = fac(a - 1) * a;
}
// 返回阶乘结果
return total;
}
int main() {
// 定义变量a用于接收用户输入的数
int a;
// 提示用户输入一个数
puts("input a number:\n");
// 读取用户输入的数
scanf("%d",&a);
// 调用fac函数计算阶乘结果
int result = fac(a);
// 输出阶乘结果
printf("result = %d",result);
}
2、汉诺塔问题
不会。
3、输入10个数,输出最大值并且输出是第几个数
#include <cstdio> // 包含标准输入输出库
#define n 10 // 定义数组的大小为10
// 定义函数用于获取两个数中的最大值
int getMax(int a, int b){
// 使用三元运算符返回较大的数
return a > b ? a : b;
}
int main() {
// 定义一个大小为n的整数数组
int a[n];
// 循环提示用户输入10个数,并存储到数组中
for (int i = 0; i < n; ++i) {
printf("input %d :", i + 1); // 提示用户输入第i+1个数
scanf("%d", &a[i]); // 读取用户输入的数并存储到数组的第i个位置
}
// 初始化最大值为数组的第一个元素
int max = a[0];
// 初始化最大值的索引为0
int max_index = 0;
// 循环遍历数组,找到最大值及其索引
for (int i = 0; i < n; ++i) {
// 使用getMax函数比较当前最大值和数组中的第i个元素
if (getMax(max, a[i]) > max) {
// 如果找到更大的值,更新最大值
max = getMax(max, a[i]);
// 更新最大值的索引
max_index = i;
}
}
// 输出最大值及其索引
printf("max is :%d and index is %d", max, max_index);
}
4、选择法对十个数进行从小到大的排序
#include <cstdio> // 包含标准输入输出库
#define n 10 // 定义数组的大小为10
// 选择法对数组进行排序
void sort(int a[], int length){
int min, temp; // min用于存储最小元素的下标,temp用于交换元素
// 外层循环,遍历数组的每个元素
for (int i = 0; i < n; ++i) {
min = i; // 假设当前元素是最小的
// 内层循环,从当前元素的下一个元素开始,寻找最小元素
for (int j = i + 1; j < n; ++j) {
// 如果找到更小的元素,更新min的值
if (a[j] < a[min]){
min = j;
}
}
// 如果找到的最小元素不是当前元素,进行交换
if (min != i){
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
}
int main() {
int a[n] = {0}; // 定义一个大小为n的整数数组,并初始化为0
int i = 0; // 定义循环变量
// 循环提示用户输入10个数,并存储到数组中
while(i < 10){
printf("input the NO.%d:", i + 1); // 提示用户输入第i+1个数
scanf("%d", &a[i]); // 读取用户输入的数并存储到数组的第i个位置
i++; // 循环变量自增
}
// 调用sort函数对数组进行排序
sort(a, n);
// 循环输出排序后的数组
for (int j = 0; j < n; ++j) {
printf("%d ", a[j]);
}
}
5、输出1到5的阶乘的值
使用局部静态变量
6、使用函数调用的方式实现求两个数的最大公约数和最小公倍数
原理:
辗转相除法基于以下原理:两个整数的最大公约数等于其中较小的数和两数相除余数的最大公约数。换句话说,如果你有两个整数 a 和 b(假设 a>b),它们的最大公约数与 b 和 amodb(即 a 除以 b 的余数)的最大公约数相同。
算法步骤
输入两个整数 a 和 b,其中 a≥b。
计算余数 r=amodb。
更新数值:将 a 的值更新为 b,将 b 的值更新为 r。
重复步骤2和3,直到 b 变为0。
结果:当 b 变为0时,a 的值即为两数的最大公约数。
示例
假设我们要计算 48 和 18 的最大公约数:
48mod18=12,更新 a=18,b=12。
18mod12=6,更新 a=12,b=6。
12mod6=0,更新 a=6,b=0。
此时,b=0,所以最大公约数是 a=6。
最小公倍数就是48*18/6=144
为什么不需要大小判断?
通用性:算法的每一步都是基于当前的
m
和n
进行的,无论它们的初始大小关系如何。算法通过不断地交换m
和n
的角色(即m
变成n
,n
变成m % n
),确保了算法的通用性和正确性。假设m=18,n=48时,因为18%48=18,所以m=48,n=18,就换过来了。
#include "stdio.h"
// 计算最大公约数的函数
// 参数 m 和 n 是需要计算最大公约数的两个整数
// 返回值是 m 和 n 的最大公约数
int gcd(int m, int n){
int temp;
// 当 n 不为 0 时,继续执行循环
while(n != 0){
// 计算 m 除以 n 的余数
temp = m % n;
// 更新 m 为 n,n 为余数 temp
m = n;
n = temp;
}
// 当 n 为 0 时,m 就是最大公约数
return m;
}
// 计算最小公倍数的函数
// 参数 M 和 N 是原始的两个整数,gcd_value 是它们的最大公约数
// 返回值是 M 和 N 的最小公倍数
int lcm(int M, int N, int gcd_value){
// 最小公倍数等于两数乘积除以它们的最大公约数
return M * N / gcd_value;
}
int main(){
int m, n;
// 提示用户输入第一个整数 m
printf("please input m: ");
// 读取用户输入的整数 m
scanf("%d", &m);
// 提示用户输入第二个整数 n
printf("please input n: ");
// 读取用户输入的整数 n
scanf("%d", &n);
// 调用 gcd 函数计算 m 和 n 的最大公约数
int max = gcd(m, n);
// 调用 lcm 函数计算 m 和 n 的最小公倍数
int min = lcm(m, n, max);
// 输出最大公约数和最小公倍数
printf("gcd=%d, lcm=%d\n", max, min);
return 0;
}
7、写三个函数计算如下方程在判别式>0、=0、<0下的根
#include "stdio.h" // 引入标准输入输出库,用于输入输出操作
#include "math.h" // 引入数学库,用于计算平方根等数学函数
// 定义全局变量,用于存储一元二次方程的系数和解
float a, b, c, dt, x1, x2;
// 当判别式大于零时,调用此函数计算两个不同的实数根并输出结果
void more_than_zero(){
x1 = (-b + sqrt(dt)) / (2 * a); // 根据求根公式计算第一个根
x2 = (-b - sqrt(dt)) / (2 * a); // 根据求根公式计算第二个根
printf("x1 = %f , x2 = %f\n", x1, x2); // 输出两个实数根
}
// 当判别式等于零时,调用此函数计算两个相等的实数根并输出结果
void equal_zero(){
x1 = x2 = (-b) / (2 * a); // 根据求根公式计算两个相等的根
printf("x1 = %f , x2 = %f\n", x1, x2); // 输出两个相等的实数根
}
// 当判别式小于零时,调用此函数输出没有实数根的信息
void small_than_zero(){
// 输出没有实数根,而是复数根的信息
printf("No real roots: x1 = %f+%fi, x2 = %f-%fi\n",
(-b) / (2 * a), sqrt(-dt) / (2 * a), (-b) / (2 * a), sqrt(-dt) / (2 * a));
}
int main(){
// 提示用户输入一元二次方程的系数 a, b, c
printf("please input a: ");
scanf("%f", &a);
printf("please input b: ");
scanf("%f", &b);
printf("please input c: ");
scanf("%f", &c);
// 计算判别式 dt = b^2 - 4ac
dt = pow(b, 2) - 4 * a * c;
// 根据判别式的值,选择不同的函数来计算根
if (dt > 0){
more_than_zero(); // 判别式大于零,有两个不同的实数根
} else if(dt == 0){
equal_zero(); // 判别式等于零,有两个相等的实数根
} else{
small_than_zero(); // 判别式小于零,没有实数根
}
return 0; // 程序结束
}
8、使用函数调用判断一个数是不是素数
#include <stdio.h>
#include <math.h>
// 函数用于判断一个数是否为素数
bool judge(int a) {
// 处理小于2的数和2的情况
if (a <= 1) {
return false; // 小于等于1的数不是素数
}
if (a == 2) {
return true; // 2是素数
}
if (a % 2 == 0) {
return false; // 排除所有大于2的偶数
}
// 只需检查到sqrt(a),且只需检查奇数
for (int i = 3; i <= sqrt(a); i += 2) {
if (a % i == 0) {
return false; // 如果a能被i整除,则a不是素数
}
}
return true; // 如果没有找到因子,则a是素数
}
int main() {
int a;
printf("Input a number: ");
scanf("%d", &a);
if (judge(a)) {
printf("%d is a prime number.\n", a);
} else {
printf("%d is not a prime number.\n", a);
}
return 0;
}
9、写个函数实现3x3矩阵转置
#include <stdio.h>
#define N 3 // 定义矩阵的大小为 3x3
int a[N][N]; // 定义一个 3x3 的矩阵 a
// 函数用于转换矩阵,即计算矩阵的转置
void convert(){
int temp;
// 遍历矩阵的上三角部分
for (int i = 0; i < N; ++i) {
// 从 i+1 开始,避免重复交换和自身交换
for (int j = i + 1; j < N; ++j) {
// 交换元素
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}
int main(){
// 输入矩阵的元素
for (int i = 0; i < N; ++i) {
printf("Input the elements of line %d\n", i + 1);
for (int j = 0; j < N; ++j) {
printf("Input the No. %d element: ", j + 1);
scanf("%d", &a[i][j]); // 读取用户输入的元素
}
printf("\n");
}
// 输出原始矩阵
printf("Original matrix:\n");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%3d", a[i][j]); // 输出矩阵元素,占3个字符宽度
}
printf("\n");
}
// 调用函数计算矩阵的转置
convert();
// 输出转置后的矩阵
printf("\nTransposed matrix:\n");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%3d", a[i][j]); // 输出转置后的矩阵元素
}
printf("\n");
}
return 0; // 程序结束
}
10、调用函数实现字符串反转
#include "stdio.h" // 引入标准输入输出库
#include "string.h" // 引入字符串处理库
#define N 100 // 定义字符串的最大长度为100
// 函数用于反转字符串
void reserve(char a[N]){
int temp; // 用于交换字符的临时变量
int len = strlen(a); // 获取字符串的长度
// 遍历字符串的前半部分
for (int i = 0; i < len / 2; ++i) {
temp = a[i]; // 保存当前字符
a[i] = a[len - i - 1]; // 将对称位置的字符赋值给当前位置
a[len - i - 1] = temp; // 将保存的字符赋值给对称位置
}
}
int main(){
char str[N]; // 定义一个字符数组,用于存储输入的字符串
printf("Input a string:\n"); // 提示用户输入字符串
gets(str); // 使用gets函数读取一行文本,包括空格,直到遇到换行符
reserve(str); // 调用reserve函数反转字符串
puts(str); // 使用puts函数输出反转后的字符串
return 0; // 程序结束
}
11、调用函数实现两个字符串连接
#include <cstdio> // 包含标准输入输出库
//#include "string" // 这里注释掉了,因为代码中没有使用到<string>库的功能
#define N 30 // 定义一个宏N,表示字符串数组的最大长度
char s1[N], s2[N]; // 定义两个字符数组s1和s2,用于存储输入的字符串
// 函数定义:实现两个字符串的拼接
void concatStr(char s1[], char s2[]) {
int i = 0, j = 0; // 定义两个索引变量i和j,分别用于遍历s1和s2
// 遍历s1,找到第一个空字符'\0'的位置,即s1的末尾
while (s1[i] != '\0' && i < N) {
i++;
}
// 遍历s2,将s2中的字符依次复制到s1的末尾
while (s2[j] != '\0' && j < N) {
s1[i++] = s2[j++]; // 将s2[j]赋值给s1[i],然后i和j分别加1
}
// 注意:这里没有显式地在s1的末尾添加'\0',但因为s1原本就有'\0',所以拼接后仍然保持字符串的格式
}
int main() {
// 提示用户输入第一个字符串
printf("input the first:\n");
gets(s1); // 使用gets函数读取用户输入的字符串,存储到s1中
// 提示用户输入第二个字符串
printf("input the second:\n");
gets(s2); // 使用gets函数读取用户输入的字符串,存储到s2中
// 调用concatStr函数,将s2拼接到s1的末尾
concatStr(s1, s2);
// 输出拼接后的结果
printf("the result is:\n");
puts(s1); // 使用puts函数输出s1的内容
return 0; // 程序正常结束
}
12、将一个字符串s1的元音字母复制到另一个字符串s2,然后输出s2
元音字母:a e i o u A E I O U
#include <cstdio> // 包含标准输入输出库
#define N 20 // 定义一个宏N,表示字符串数组的最大长度
// 函数定义:将s1中的元音字母复制到s2中
void copy(char s1[], char s2[]) {
int i = 0, j = 0; // 定义两个索引变量i和j,分别用于遍历s1和s2
// 遍历s1字符串
while (s1[i] != '\0' && i < N) { // 当s1[i]不是字符串结束符'\0'且i小于数组大小N时
// 判断s1[i]是否为元音字母(包括大小写)
if (s1[i] == 'a' || s1[i] == 'e' || s1[i] == 'i' || s1[i] == 'o' || s1[i] == 'u' ||
s1[i] == 'A' || s1[i] == 'E' || s1[i] == 'I' || s1[i] == 'O' || s1[i] == 'U') {
s2[j++] = s1[i]; // 如果是元音字母,则将其复制到s2中,并将j加1
}
i++; // 继续遍历s1的下一个字符
}
s2[j] = '\0'; // 在s2的末尾添加字符串结束符'\0'
}
int main() {
char s1[N], s2[N]; // 定义两个字符数组s1和s2,分别用于存储输入的字符串和结果字符串
// 提示用户输入字符串
puts("input the string:");
gets(s1); // 使用gets函数读取用户输入的字符串,存储到s1中
// 调用copy函数,将s1中的元音字母复制到s2中
copy(s1, s2);
// 输出结果字符串s2
printf("s2:");
puts(s2); // 使用puts函数输出s2的内容
return 0; // 程序正常结束
}
在C语言中,字符串操作函数(如
puts
、printf
等)依赖字符串的结束符'\0'
来确定字符串的结束位置。如果不显式地添加'\0'
,puts
函数会继续读取s2
数组之后的内存内容,直到遇到一个'\0'
为止。这可能会导致输出乱码或程序崩溃。
13、输入1990输出1 9 9 0
#include <cstdio> // 包含标准输入输出库
#include <cstring> // 包含字符串处理函数的头文件
#define N 20 // 定义一个宏N,表示字符串数组的最大长度
// 函数定义:将字符串s中的字符按照“字符-空格”的模式重新排列
void convert(char s[]) {
int len = 2 * strlen(s) - 1; // 计算新字符串的长度,每个字符之间插入一个空格
char s1[N]; // 定义一个临时数组s1,用于存储原始字符串
int j = 0; // 定义一个索引变量j,用于遍历s1
// 使用strcpy函数将s的内容复制到s1中
strcpy(s1, s);
// 遍历新字符串的每个位置
for (int i = 0; i < len; ++i) {
// 如果索引i是偶数,则将s1中的字符复制到s[i]中
// 否则,在s[i]中插入一个空格
s[i] = i % 2 == 0 ? s1[j++] : ' ';
}
}
int main() {
char s[N]; // 定义一个字符数组s,用于存储用户输入的字符串
// 提示用户输入字符串
puts("input the string:");
gets(s); // 使用gets函数读取用户输入的字符串
// 调用convert函数,将字符串s中的字符按照“字符-空格”的模式重新排列
convert(s);
// 输出结果
puts("s:");
puts(s); // 使用puts函数输出处理后的字符串s
return 0; // 程序正常结束
}
14、调用函数实现计算字符串中字母、数字、空格和其他字符的个数
#include <cstdio>
#define N 50
static int zimu,shuzi,space,others;
void compute(char s[]){
int i = 0;
while(i < N && s[i] != '\0'){
// 判断字符是否为字母(包括大小写)
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
zimu++; // 字母计数加1
}
// 判断字符是否为数字
else if (s[i] >= '0' && s[i] <= '9') {
shuzi++; // 数字计数加1
}
// 判断字符是否为空格
else if (s[i] == ' ') {
space++; // 空格计数加1
}
// 其他字符
else {
others++; // 其他字符计数加1
}
i++;
}
}
int main(){
char s[N];
puts("input the string:");
gets(s);
compute(s);
printf("zimu:%d,shuzi:%d,space:%d,others:%d",zimu,shuzi,space,others);
}
15、输出字符串中最长的单词
#include <stdio.h>
#include <string.h>
#define N 50
// 找到最长单词的起始位置
int longest(char s[]) {
int i = 0; // 用于遍历字符串的索引
int len = 0; // 当前单词的长度
int maxLen = 0; // 记录最长单词的长度
int start = 0; // 当前单词的起始位置
int maxStart = 0; // 最长单词的起始位置
// 遍历字符串,直到遇到字符串结束符'\0'
while (s[i] != '\0') {
if (s[i] == ' ') { // 如果当前字符是空格
if (len > maxLen) { // 检查当前单词的长度是否大于已记录的最大长度
maxLen = len; // 更新最大长度
maxStart = start; // 更新最长单词的起始位置
}
len = 0; // 重置当前单词长度为0
start = i + 1; // 更新下一个单词的起始位置
} else { // 如果当前字符不是空格
len++; // 当前单词长度加1
}
i++; // 移动到下一个字符
}
// 检查最后一个单词
// 原因:在循环中,只有遇到空格时才会更新maxLen和maxStart
// 但如果字符串的最后一个单词后面没有空格(即它是字符串的最后一个单词),则它的长度和起始位置不会在循环中被更新
if (len > maxLen) {
maxLen = len; // 更新最大长度
maxStart = start; // 更新最长单词的起始位置
}
return maxStart; // 返回最长单词的起始位置
}
int main() {
char s[N]; // 定义一个字符数组s,用于存储用户输入的字符串
// 提示用户输入字符串
puts("input the string:");
gets(s); // 读取用户输入的字符串
// 调用longest函数,找到最长单词的起始位置
int maxStart = longest(s);
// 从最长单词的起始位置开始,输出最长单词
int i = maxStart;
while (s[i] != '\0' && s[i] != ' ') { // 遍历最长单词,直到遇到字符串结束符'\0'或空格
printf("%c", s[i]); // 输出当前字符
i++; // 移动到下一个字符
}
printf("\n"); // 输出换行符,结束输出
return 0; // 程序正常结束
}
16、冒泡法对输入的10个字符从小到大排序
#include <cstdio>
#include <cstring>
#define N 20
// 冒泡排序函数,对字符串中的字符进行升序排序
void bubble(char s[]) {
int len = strlen(s); // 获取字符串的长度
int flag; // 用于标记是否发生了交换
int i, j; // 外层循环变量i和内层循环变量j
char temp; // 用于交换字符的临时变量
// 外层循环控制排序的轮数,总共需要len-1轮
for (i = 0; i < len - 1; ++i) {
flag = 0; // 每轮开始时,假设字符串已经排序好
// 内层循环控制每轮的比较和交换操作
for (j = 0; j < len - i - 1; ++j) {
// 如果当前字符大于下一个字符,则交换它们
if (s[j] > s[j + 1]) {
temp = s[j]; // 保存当前字符
s[j] = s[j + 1]; // 将下一个字符移到当前位置
s[j + 1] = temp; // 将保存的字符移到下一个位置
flag = 1; // 发生了交换,标记为1
}
}
// 如果在一轮中没有发生任何交换,说明字符串已经排序完成,可以提前退出
if (flag == 0) {
break;
}
}
}
int main() {
char s[N]; // 定义一个字符数组s,用于存储用户输入的字符串
// 提示用户输入字符串
puts("input the string:");
gets(s); // 读取用户输入的字符串
// 调用bubble函数,对字符串中的字符进行升序排序
bubble(s);
// 输出排序后的结果
puts("result:");
puts(s);
return 0; // 程序正常结束
}
17、牛顿迭代法求方程x=1附近的根,精度为10(-3)
a = 1,b=2,c=3,d=4
#include <cstdio>
#include <cmath>
float a, b, c, d; // 定义一元三次方程的系数
// 计算一元三次方程 f(x) = ax^3 + bx^2 + cx + d
float fx(float x) {
return a * pow(x, 3) + b * pow(x, 2) + c * x + d;
}
// 计算一元三次方程的导数 f'(x) = 3ax^2 + 2bx + c
float fxd(float x) {
return 3 * a * pow(x, 2) + 2 * b * x + c;
}
// 使用牛顿法求解一元三次方程的根
float solut() {
float x0 = 1; // 初始猜测值
float x1 = x0 - fx(x0) / fxd(x0); // 牛顿法迭代公式
// 迭代直到 x1 和 x0 的差值小于 1e-3
while (abs(x1 - x0) > 1e-3) {
x0 = x1; // 更新 x0
x1 = x0 - fx(x0) / fxd(x0); // 再次使用牛顿法迭代公式
}
return x1; // 返回求得的根
}
int main() {
puts("input a,b,c,d:"); // 提示用户输入系数
scanf("%f,%f,%f,%f", &a, &b, &c, &d); // 读取用户输入的系数
// 调用 solut 函数求解方程的根
printf("x=%10.7f", solut()); // 输出求得的根,保留 7 位小数
return 0; // 程序正常结束
}
18、递归实现N阶勒让德多项式的值
#include <cstdio>
// 计算勒让德多项式 P_n(x)
float px(int n, float x) {
if (n == 0) {
return 1; // P_0(x) = 1
} else if (n == 1) {
return x; // P_1(x) = x
} else {
// 使用递归公式计算 P_n(x)
// 递归公式:P_n(x) = ((2n-1)xP_{n-1}(x) - (n-1)P_{n-2}(x)) / n
return ((2 * n - 1) * x * px(n - 1, x) - (n - 1) * px(n - 2, x)) / n;
}
}
int main() {
int n;
float x;
puts("input the 'n' and 'x':");
// 读取用户输入的 n 和 x
// 注意:输入格式应该是两个整数,用逗号分隔
scanf("%d,%f", &n, &x);
// 调用 px 函数计算 P_n(x)
printf("p%d(%.2f) = %.6f\n", n, x, px(n, x));
return 0;
}
19、输入10个学生的5门成绩,实现下面功能
(1)计算每个学生的平均分
(2)计算每门课的平均分
(3)计算最高分对应的学生和课程
(4)计算平均值方差
#include <cstdio>
#include <cmath>
#define M 10 // 定义学生数量
#define N 5 // 定义课程数量
float averageStudent[M]; // 每个学生的平均分
float averageCourses[N]; // 每门课程的平均分
int student = 0, course = 0; // 最高分数对应的学生和课程
float fc = 0; // 平均分方差
// 计算每个学生的平均分
void getAverageStudent(float scores[M][N]) {
float sum = 0; // 用于累加分数
for (int i = 0; i < M; ++i) { // 遍历每个学生
for (int j = 0; j < N; ++j) { // 遍历每门课程
sum += scores[i][j]; // 累加该学生的分数
}
averageStudent[i] = sum / N; // 计算该学生的平均分
sum = 0; // 重置sum为0,用于下一个学生的分数累加
}
}
// 计算每门课程的平均分
void getAverageCourses(float scores[M][N]) {
float sum = 0; // 用于累加分数
for (int i = 0; i < N; ++i) { // 遍历每门课程
for (int j = 0; j < M; ++j) { // 遍历每个学生
sum += scores[j][i]; // 累加该课程的分数
}
averageCourses[i] = sum / M; // 计算该课程的平均分
sum = 0; // 重置sum为0,用于下一门课程的分数累加
}
}
// 找出最高分数的学生和课程
void getTop(float scores[M][N]) {
float maxScore = 0; // 用于存储最高分数
for (int i = 0; i < M; ++i) { // 遍历每个学生
for (int j = 0; j < N; ++j) { // 遍历每门课程
if (scores[i][j] > maxScore) { // 如果当前分数大于最高分数
maxScore = scores[i][j]; // 更新最高分数
student = i; // 更新最高分数对应的学生编号
course = j; // 更新最高分数对应的课程编号
}
}
}
}
// 计算平均分方差
float getFc(float scores[M][N]) {
float sumXi = 0, sumXi2 = 0, result;
float mu = 0; // 所有学生平均分的平均值
// 计算所有学生平均分的平均值
for (int i = 0; i < M; ++i) {
sumXi += averageStudent[i];
}
mu = sumXi / M;
// 计算方差
for (int i = 0; i < M; ++i) {
sumXi2 += pow(averageStudent[i] - mu, 2);
}
result = sumXi2 / M;
return result;
}
int main() {
float scores[M][N] = { // 定义学生成绩数组
{60, 90.0, 78.5, 92.0, 88.0},
{60, 98.5, 90.0, 63.0, 80.5},
{60, 66.5, 92.0, 85.0, 78.5},
{60, 92.5, 85.0, 76.0, 90.0},
{60, 85.0, 90.0, 92.5, 88.0},
{60, 88.0, 78.5, 36.0, 85.5},
{60, 56.0, 92.5, 88.0, 90.0},
{60, 56.0, 85.0, 100, 92.0},
{60, 82.0, 45.5, 90.0, 99.0},
{60, 88.0, 77.0, 70.5, 90.0}
};
getAverageStudent(scores); // 计算每个学生的平均分
printf("averageStudent:");
for (int i = 0; i < M; ++i) {
printf("%4.2f\t", averageStudent[i]);
}
printf("\n");
getAverageCourses(scores); // 计算每门课程的平均分
printf("averageCourses:");
for (int i = 0; i < N; ++i) {
printf("%4.2f\t", averageCourses[i]);
}
printf("\n");
getTop(scores); // 找出最高分数的学生和课程
printf("the max student is:%d and the course is:%d\n", student, course);
printf("the result is:%4.2f", getFc(scores)); // 输出平均分方差
}
20、写几个函数
(1)输入10个职工的姓名和员工号。
(2)职工号由小到大排序,姓名也随之改变。
(3)输出职工号,用折半查找找出姓名。
#include <cstdio>
#define N 5
typedef struct {
int No; // 用户编号
char username[5]; // 用户名
} User;
// 折半插入排序
void sort(User user[N]) {
int mid, j; // 中间索引和循环变量
User temp; // 临时变量,用于存储当前待插入的元素
for (int i = 1; i < N; ++i) { // 从第二个元素开始,逐个插入到前面已排序的序列中
temp = user[i]; // 将当前元素存储到临时变量中
int low = 0; // 设置折半查找的下界
int high = i - 1; // 设置折半查找的上界
while (low <= high) { // 当下界小于等于上界时,继续折半查找
mid = (low + high) / 2; // 计算中间索引
if (user[mid].No > temp.No) { // 如果中间元素大于待插入元素
high = mid - 1; // 调整上界
} else {
low = mid + 1; // 调整下界
}
}
for (j = i - 1; j >= low; --j) { // 将从插入位置到当前元素之间的所有元素向后移动一位
user[j + 1] = user[j];
}
user[low] = temp; // 将待插入元素插入到正确的位置
}
}
// 折半查找
User getUser(User user[N], int id) {
int low = 0; // 设置折半查找的下界
int high = N - 1; // 设置折半查找的上界
int mid; // 中间索引
while (low <= high) { // 当下界小于等于上界时,继续折半查找
mid = (low + high) / 2; // 计算中间索引
if (id == user[mid].No) { // 如果中间元素的编号等于目标编号
return user[mid]; // 返回该用户
} else if (id > user[mid].No) { // 如果目标编号大于中间元素的编号
low = mid + 1; // 调整下界
} else {
high = mid - 1; // 调整上界
}
}
// 如果未找到目标用户,返回一个特殊的用户对象
User notFound = {-1, "N/A"};
return notFound;
}
int main() {
User user[N]; // 定义一个用户数组
int id; // 定义一个变量,用于存储用户输入的编号
// 输入用户信息
for (int i = 0; i < N; ++i) {
printf("please input the No.%d's id and username: ", i + 1);
scanf("%d", &user[i].No); // 输入用户编号
scanf("%s", user[i].username); // 输入用户名
printf("\n");
}
// 输出用户信息
for (int i = 0; i < N; ++i) {
printf("id:%d and name:%s\n", user[i].No, user[i].username);
}
// 对用户数组进行排序
sort(user);
// 输入要查找的用户编号
printf("input the user's id:");
scanf("%d", &id);
// 调用折半查找函数,查找用户
User result = getUser(user, id);
if (result.No == -1) {
printf("User not found.\n");
} else {
printf("the id is: %d and the username is: %s\n", result.No, result.username);
}
}
21、输入十六进制输出十进制
十六进制转十进制:
十六进制数是基于16的数制,使用数字0-9和字母A-F(或a-f)表示,其中A=10, B=11, C=12, D=13, E=14, F=15。
要将十六进制数转换为十进制数,可以使用以下公式:
十进制数=∑i=0n(di×16i)
其中,di是十六进制数的第i位数字(从右向左数,最右边的位是0),n是十六进制数的位数减1。
示例: 将十六进制数
1A3
转换为十进制数。1A316=1×162+A×161+3×160 =1×256+10×16+3×1 =256+160+3 =41910
#include <cstdio>
#include <cstring>
#include <cmath>
#define N 10 // 定义数组的最大长度
// 函数:将十六进制字符串转换为十进制数
double convert(char num[]) {
int len = strlen(num); // 获取字符串的长度
double sum = 0; // 用于存储最终的十进制结果
// 从左到右遍历字符串
for (int i = 0; i < len; ++i) {
// 如果是数字字符('0'到'9')
if (num[i] >= '0' && num[i] <= '9') {
// 将字符转换为对应的数值,并乘以16的相应幂次
sum += (num[i] - '0') * pow(16, len - 1 - i);
}
// 如果是小写字母('a'到'f')
else if (num[i] >= 'a' && num[i] <= 'f') {
// 将字符转换为对应的数值,并乘以16的相应幂次
sum += (num[i] - 'a' + 10) * pow(16, len - 1 - i);
}
// 如果是大写字母('A'到'F')
else if (num[i] >= 'A' && num[i] <= 'F') {
// 将字符转换为对应的数值,并乘以16的相应幂次
sum += (num[i] - 'A' + 10) * pow(16, len - 1 - i);
}
}
return sum; // 返回最终的十进制结果
}
int main(){
char num[N]; // 定义一个字符数组用于存储输入的十六进制数
puts("input the 16:"); // 提示用户输入十六进制数
gets(num); // 读取用户输入的字符串
// 调用convert函数将十六进制数转换为十进制数,并输出结果
printf("%s convert 10 is %3.1f(10)", num, convert(num));
}
22、递归实现将int类型的数据转为字符串😒
#include <cstdio>
// 函数:将十进制整数转换为字符串形式并逐位输出
void convert(int num){
// 如果是负数,先输出负号,并将负数转换为正数
if (num < 0) {
putchar('-'); // 输出负号
num = -num; // 将负数转换为正数
}
// 如果当前数的高位不为0,递归调用 convert 函数处理更高位
if (num / 10 != 0) {
convert(num / 10); // 递归调用,处理更高位
}
// 输出当前位
putchar(num % 10 + '0'); // num % 10 得到当前位的数字,加上 '0' 的ASCII值将其转换为字符
}
int main(){
int num;
// 提示用户输入一个整数
puts("input the num:");
// 读取用户输入的整数
scanf("%d", &num);
// 调用 convert 函数进行转换并输出
convert(num);
// 输出换行符,确保输出格式正确
putchar('\n');
return 0;
}
23、输入年月日输出是该年的第几天
#include <cstdio>
#define N 7
// 判断今年是不是闰年
bool judge(int year) {
// 如果年份能被4整除但不能被100整除,或者能被400整除,则是闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 计算从年初到指定日期的总天数
int compute(int year, int month, int day) {
int sum = 0; // 用于累加天数
// 遍历从1月到指定月份的所有月份
for (int i = 1; i <= month; ++i) {
int j = i - 1; // 当前月份之前的完整月份
// 如果是2月
if (j == 2) {
// 如果是闰年,2月有29天,否则28天
if (judge(year)) {
sum += 29;
} else {
sum += 28;
}
}
// 如果是1月、3月、5月、7月、8月、10月、12月
else if (j == 1 || j == 3 || j == 5 || j == 7 || j == 8 || j == 10 || j == 12) {
sum += 31; // 这些月份都有31天
}
// 如果是4月、6月、9月、11月
else if (j == 4 || j == 6 || j == 9 || j == 11) {
sum += 30; // 这些月份都有30天
}
}
// 加上指定日期的天数
return sum + day;
}
int main() {
int year, month, day; // 用于存储输入的年、月、日
// 提示用户输入年份
puts("input the year:");
// 读取用户输入的年份
scanf("%d", &year);
// 提示用户输入月份
puts("input the month:");
// 读取用户输入的月份
scanf("%d", &month);
// 提示用户输入日期
puts("input the day:");
// 读取用户输入的日期
scanf("%d", &day);
// 调用compute函数计算从年初到指定日期的总天数,并输出结果
printf("the sum is:%d", compute(year, month, day));
}