上海海事大学自动化专业C语言课程代码参考(第十四周)

不知道大家最近有没有被ChatGPT刷屏啊,作为一个语言模型,可以调教成你的形状…啊不对,调教成你想让它成为的样子,非常好玩。我有尝试着让它帮忙写咱的C语言作业,效果还是很不错的,可以看来看看。

目录

上机实验

6-11          统计字符出现次数

6-12          字符串逆序

6-13          字符串字母大小写转换

6-14          矩阵各行元素之和

6-15          阵运算

6-16          找鞍点

6-17          期末分数排序

6-18          选择法排序

6-19           找出不是两个数组共有的元素

6-20          打印杨辉三角

结语


上机实验

6-11          统计字符出现次数

本题要求编写程序,统计并输出某给定字符在给定字符串中出现的次数。

输入格式:

输入第一行给出一个以回车结束的字符串(少于80个字符);第二行输入一个字符。

输出格式:

在一行中输出给定字符在给定字符串中出现的次数。

输入样例:

programming is More fun!

m

输出样例:

2

很简单的题目,遍历字符串即可。这种题目丢给ChatGPT做会怎么样呢?我们试试:

 结果非常的有趣,它完美地输出了这一个程序,并且使用了 string.h 内的函数 gets() !既然出现了gets()那我们就说说吧。这个函数输入一个char指针,即字符串头指针。函数会在输入缓冲区读一条字符串,存入这个指针的位置。详细的说明可以看这里。

直接回复没有缩进,看着难受,但是没关系,现在很多功能强大的IDE都能帮我们完成代码格式化。我们测试无误之后就能将这一段代码当作我们的作业了(

#include 
#include int main()
{char a[100], b;int i, sum = 0;gets(a);scanf("%c", &b);for (i = 0; i < strlen(a); i++){if (a[i] == b)sum++;}printf("%d\n", sum);return 0;
}

好!很有精神!

6-12          字符串逆序

本题要求编写程序,输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。

输入格式:

输入在一行中给出一个不超过80个字符长度的、以回车结束的非空字符串。

输出格式:

在一行中输出逆序后的字符串。

输入样例:

Hello World!

输出样例:

!dlroW olleH

也是很简单,只需要找到字符串的结尾就行了。同样的,我们再拿ChatGPT来试试:

#include 
#include int main()
{char a[100];int i;gets(a);for (i = strlen(a) - 1; i >= 0; i--)printf("%c", a[i]);return 0;
}

可以看到,在这一段程序中,出现了另一个函数 strlen() 。这个函数是读取字符串长度。为防止混淆,在这里说一下strlen和sizeof的区别。

sizeof返回的是整个堆的长度,也就是已分配内存的长度。在这个例子内,sizeof(a)返回的值为100;而strlen计算的是从开始到字符串结束,也就是到‘\0’的长度。所以它们两个的返回值并不一样。

了解了strlen之后,我们很容易就明白,程序是倒序的单个字符打印。

6-13          字符串字母大小写转换

本题要求编写程序,对一个以“#”结束的字符串,将其小写字母全部转换成大写字母,把大写字母全部转换成小写字母,其他字符不变输出。

输入格式:

输入为一个以“#”结束的字符串(不超过50个字符)。

输出格式:

在一行中输出大小写转换后的结果字符串。

输入样例:

Hello World! 123#

输出样例:

hELLO wORLD! 123

这一题也是非常简单。在看到题目之后直接就能注意到,大写字母和小写字母的ASCII码的范围并不一样,并且遵循某种转化关系。只需要判断字符的大小,并计算即可。这部分的代码如下:

#include 
#include int main()
{char a[100];int i;gets(a);for (i = 0; i < strlen(a) && a[i] != '#'; i++){if (a[i] >= 'a' && a[i] <= 'z')printf("%c", a[i] - 32);else if (a[i] >= 'A' && a[i] <= 'Z')printf("%c", a[i] + 32);elseprintf("%c", a[i]);}return 0;
}

但是,有没有更简单的方法呢?当然有!ChatGPT给出了这样的方法:

#include 
#include 
#include int main()
{char a[100];int i;gets(a);for (i = 0; i < strlen(a) && a[i] != '#'; i++){if (isupper(a[i]))printf("%c", tolower(a[i]));else if (islower(a[i]))printf("%c", toupper(a[i]));elseprintf("%c", a[i]);}return 0;
}

可以注意到,这里多用了一个头文件。尖括号表示这是C语言标准头文件,也就是正常的编译器都会自带的头文件。

这里有两对、四个新的函数"isupper" "tolower" "islower" "toupper"。

这四个函数的意思就和字面上一样,判断是否为大写字母、将大写字母转换成小写字母、判断是否为小写字母、将小写字母转换为大写字母。可以看到,用了这个函数能稍微简化一点点开始我们所写的代码。

6-14          矩阵各行元素之和

本题要求编写程序,求一个给定的m×n矩阵各行元素之和。

输入格式:

输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间以空格分隔。

输出格式:

每行输出对应矩阵行元素之和。

输入样例:

3 2

6 3

1 -8

3 12

输出样例:

9

-7

15

这题也是并不复杂。首先将头两位数字保存,作为后续循环的循环次数;然后开始循环,每次循环只读一位,读完缓冲区为止。

代码如下:

#include int main()
{int m, n, i, j, a[10][10], sum;scanf("%d%d", &m, &n);for (i = 0; i < m; i++){sum = 0;for (j = 0; j < n; j++){scanf("%d", &a[i][j]);sum = sum + a[i][j];}printf("%d\n", sum);}return 0;
}

6-15          阵运算

本题要求编写程序,给定一个n×n的方阵,计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。

输入格式:

输入第一行给出正整数n(1

输出格式:

在一行中给出该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。

输入样例:

4

2 3 4 1

5 6 1 1

7 1 8 1

1 1 1 1

输出样例:

35

这一题也并不复杂,只需要遍历二维数组,再判断当前的数是否符合条件即可。代码如下:

#include int main()
{int a[11][11], n, i, j, sum = 0;scanf("%d", &n);for (i = 1; i <= n; i++)//录入部分for (j = 1; j <= n; j++)scanf("%d", &a[i][j]);for (i = 1; i <= n; i++)//计算部分for (j = 1; j <= n; j++){if (i != n && j != n && j != n - i + 1)sum += a[i][j];}printf("%d", sum);return 0;
}

6-16          找鞍点

本题要求编写程序,求一个给定的n阶方阵的鞍点。一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

输入格式:

输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。

输出格式:

输出在一行中按照“行下标列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。

输入样例1:

4

1 7 4 1

4 8 3 6

1 6 1 2

0 7 8 9

输出样例1:

2 1

输入样例2:

2

1 7

4 1

输出样例2:

NONE

这题的重点在于,如何固定二维数组的某一位而遍历另一位。一种实现方法如下:

#include int main()
{int a[10][10], n, i, j, max, k, flag = 0;scanf("%d", &n);for (i = 0; i < n; i++)//数据录入for (j = 0; j < n; j++)scanf("%d", &a[i][j]);for (i = 0; i < n; i++){max = a[i][0];k = 0;for (j = 1; j < n; j++)if (a[i][j] > max){max = a[i][j];k = j;}for (j = 0; j < n; j++)if (a[j][k] < max)break;if (j == n){printf("%d %d", i, k);flag = 1;break;}}if (flag == 0)printf("NONE");return 0;
}

6-17          期末分数排序

本题要求编写程序,考试结束了,全班同学的分数都出来了。老师需要对分数做一次排序,看看从高到低,分数的排列是怎样的。

输入格式:

第一行是一个n,表示班级同学的人数,1<=n<=5000。第二行开始有n个分数,0<=分数<=100,分数都是整数,没有零点五分。

输出格式:

输出排序后的分数,按照从大到小排列,相同的分数排在一起,每两个分数之间间隔一个空格。

输入样例:

10

0 60 73 60 82 90 100 18 55 84

输出样例:

100 90 84 82 73 60 60 55 18 0

这题我们可以用冒泡排序。冒泡排序老师上课有讲过,咱便不再赘述了。直接看代码吧:

#include #define SWAP(a, b)    \{                 \int temp = a; \a = b;        \b = temp;     \}int main()
{int a[5000], n, i, j;scanf("%d", &n);for (i = 1; i <= n; i++)scanf("%d", &a[i]);
//****************************************************冒泡排序本体for (i = 1; i <= n; i++)for (j = 1; j <= n - i; j++)if (a[j] < a[j + 1])SWAP(a[j], a[j + 1]);
//****************************************************for (i = 1; i <= n; i++)printf("%d%c", a[i], i == n ? '\n' : ' ');return 0;
}

可以看到这里有几行我们不曾见过的写法,我们来看看。

首先是第三行的define定义函数。这种写法的好处是,它可以直接完成一种类似函数的效果,但是却能调用外面一级函数内的局部变量。或者说,在C语言中,使用#define定义的宏是不占用内存空间的。在使用#define定义宏时,编译器会把宏展开为该宏定义的内容,但不会为宏开辟内存空间。例如:

#define SWAP(a,b) {int temp=a;a=b;b=temp;}

这个宏定义的作用是实现两个变量的交换,但在程序运行时,并不会为宏开辟内存空间。

那么如何完成多行的宏定义呢?很简单,在行尾加 '\' 即可。于是,就有了我们代码的3~8行。

这种实现过程不用宏定义则需要借助指针。例如:

void swap(int *a, int *b)
{int temp = *a;*a = *b;*b = temp;
}

上面的swap函数也实现了两个变量的交换,在函数被调用时,编译器会为该函数开辟内存空间,在该函数运行时,系统会把函数所需的参数和变量放到这段内存中,运行完后再释放掉。

6-18          选择法排序

本题要求编写程序,将给定的n个整数从大到小排序后输出。

输入格式:

输入第一行给出一个不超过100的正整数n。第二行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

输入样例:

4

5 1 7 6

输出样例:

7 6 5 1

选择排序也是讲过的,我们用同样的办法swap就可以了:

#include #define SWAP(a, b)    \{                 \int temp = a; \a = b;        \b = temp;     \}int main()
{int a[100], n, i, j, k;scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d", &a[i]);for (i = 0; i < n; i++){k = i;for (j = i; j < n; j++)if (a[j] > a[k])k = j;//找出最大的SWAP(a[i], a[k]);}for (i = 0; i < n; i++)printf("%d%c", a[i], i == n ? '\n' : ' ');return 0;
}

6-19           找出不是两个数组共有的元素

本题要求编写程序,给定两个整型数组,找出不是两者共有的元素。

输入格式:

输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。

输出格式:

在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。

输入样例:

10 3 -5 2 8 0 3 5 -15 9 100

11 6 4 8 2 6 -5 9 0 100 8 1

输出样例:

3 5 -15 6 4 1

这一题很简单,嵌套一次循环即可。示例的代码如下:

#include int main()
{int a[25], b[25], n, m, i, j, flag;scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d", &a[i]);scanf("%d", &m);for (i = 0; i < m; i++)scanf("%d", &b[i]);for (i = 0; i < n; i++){flag = 1;for (j = 0; j < m; j++)if (a[i] == b[j]){flag = 0;break;}if (flag)printf("%d ", a[i]);}return 0;
}

6-20          打印杨辉三角

本题要求编写程序,按照规定格式打印前n行杨辉三角。

输入格式:

输入在一行中给出n(1≤n≤10)。

输出格式:

以正三角形的格式输出前n行杨辉三角。每个数字占固定4位。

输入样例:

6

输出样例:

          1

        1   1

      1   2   1

    1   3   3   1

  1   4   6   4   1

1   5  10  10   5   1

我们是不是写过这道题……?好像是写过的,不过不太想找了。我们现在用二维数组来写。代码如下:

#include int main()
{int n, a[10][10];scanf("%d", &n);a[0][0] = 1;for (int i = 1; i < n; i++){a[i][0] = 1;for (int j = 1; j < i; j++){a[i][j] = a[i - 1][j] + a[i - 1][j - 1];}a[i][i] = 1;}for (int i = 0; i < n; i++){for (int k = 0; k < n - i - 1; k++){printf("  ");}for (int j = 0; j <= i; j++){printf("%4d", a[i][j]);}printf("\n");}return 0;
}

结语

不知道你有没有发现,这次的代码风格和以往的有很大不同。这是为什么呢?

因为基本全部代码均由ChatGPT生成,我只做了一点点修改,欸嘿。

不知道你怎么看待这种情况,那么,下周见

(不知道这种算不算原创,如有侵权请联系删除


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部