c语言程序设计第五版课后答案谭浩强 第六章习题答案

您所在的位置:网站首页 c语言程序第三版答案解析 c语言程序设计第五版课后答案谭浩强 第六章习题答案

c语言程序设计第五版课后答案谭浩强 第六章习题答案

2024-07-12 12:21| 来源: 网络整理| 查看: 265

第六章:利用数组处理批量数据 1. 用筛选法求100之内的素数

【答案解析】

素数:约数为1和该数本身的数字称为素数,即质数

筛选法:又称为筛法。先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛”,简称“筛法”。(另一种解释是当时的数写在纸草上,每要划去一个数,就把这个数挖去,寻求质数的工作完毕后,这许多小洞就像一个筛子。)

【代码实现】

//用筛选法求100以内的素数 #include int main() { int i, j, k = 0; // 将数组汇总每个元素设置为:1~100 int a[100]; for (i = 0; i < 100; i++) a[i] = i+1; // 因为1不是素数,把a[0]用0标记 // 最后一个位置数字是100,100不是素数,因此循环可以少循环一次 a[0] = 0; for (i = 0; i < 99; i++) { // 用a[i]位置的数字去模i位置之后的所有数据 // 如果能够整除则一定不是素数,该位置数据用0填充 for (j = i + 1; j < 100; j++) { if (a[i] != 0 && a[j] != 0) { //把不是素数的都赋值为0 if (a[j] % a[i] == 0) a[j] = 0; } } } printf(" 筛选法求出100以内的素数为:\n"); for (i = 0; i < 100; i++) { //数组中不为0的数即为素数 if (a[i] != 0) printf("%3d", a[i]); } printf("\n"); return 0; }

【运行结果】

2. 用选择法对10个整数排序

【答案解析】

选择排序原理:

总共两个循环,外循环控制选择的趟数,内循环控制具体选择的方式。

用maxPos标记区间中首元素位置,然后用后序元素依次与maxPos标记的元素进行比较,如果有元素大于maxPos位置的元素,用maxPos标记该元素的位置,直到区间的末尾。

该趟选择完成后,即找到该区间中最大元素,如果maxPos标记的最大元素不在区间末尾,用maxPos位置元素与区间末尾的元素进行交换。

继续新一趟选择,直到区间中剩余一个元素

【代码实现】

#include int main() { int array[] = {2,8,3,9,5,7,1,4,0,6}; int size = sizeof(array) / sizeof(array[0]); // 输出原数组 printf("排序前数组中数据为:"); for (int i = 0; i < size; ++i) printf("%d ", array[i]); printf("\n"); // 选择排序过程: // 外循环控制选择的趟数,总共选择size-1趟, // 减1是因为最后一趟选择区间中剩余一个元素,该趟选择可以忽略 for (int i = 0; i < size-1; ++i) { // 用maxPos标记[0, size-i)区间中最大元素 // 在该趟选择没有开始前,默认认为0号位置就是最大元素 int maxPos = 0; for (int j = 1; j < size - i; ++j) { // 遍历区间[0, size-i)中元素,如果有元素比maxPos位置元素大,maxPos记录该元素位置 if (array[j] > array[maxPos]) maxPos = j; } // 如果最大元素不在区间末尾时,将最大元素与区间末尾元素交换 if (maxPos != size - i - 1) { int temp = array[maxPos]; array[maxPos] = array[size - i - 1]; array[size - i - 1] = temp; } } // 输出原数组 printf("选择排序后数组中数据为:"); for (int i = 0; i < size; ++i) printf("%d ", array[i]); printf("\n"); return 0; }

【结果截屏】

优化:既然一趟选择能找到最大的元素,那么也可以找到最小的元素,因此在一趟中可以找到最小和最大两个元素,最小元素放在区间左侧,最大元素放在区间右侧,可以减少选择的趟数。

#include int main() { int array[] = {2,8,3,9,5,7,1,4,0,6}; int size = sizeof(array) / sizeof(array[0]); // 输出原数组 printf("排序前数组中数据为:"); for (int i = 0; i < size; ++i) printf("%d ", array[i]); printf("\n"); int begin = 0, end = size - 1; // [begin, end]区间中进行选择 while (begin < end) { int maxPos = begin; // 标记区间中最大元素的位置 int minPos = begin; // 标记区间中最小元素的位置 int index = begin + 1; while (index array[maxPos]) maxPos = index; if (array[index] < array[minPos]) minPos = index; ++index; } // 如果最大元素不在区间末尾,则交换 if (maxPos != end) { int temp = array[maxPos]; array[maxPos] = array[end]; array[end] = temp; } // 如果在交换前区间末尾刚好存储的是最小的元素,则最小的元素被交换到maxPos位置 // 此时需要更新minPos if (minPos == end) minPos = maxPos; // 如果最小元素不在区间起始位置,则交换 if (minPos != begin) { int temp = array[minPos]; array[minPos] = array[begin]; array[begin] = temp; } // 最大与最小元素已经在区间的起始和末尾的位置, // 因此begin往后移动,end往前移动 begin++; end--; } // 输出原数组 printf("选择排序后数组中数据为:"); for (int i = 0; i < size; ++i) printf("%d ", array[i]); printf("\n"); return 0; } 3. 求一个3 X 3的整形矩阵对角线元素之和

【答案解析】

矩阵:即二维数组,矩阵行和列相等的二维数组称为方阵。

1 2 3

4 5 6

7 8 9

左上角到右下角对角线上数字:行下标和列下标相等

右上角到左下角对角线上数字:列下标减1 行下标加一

通过两个循环来取到对角线上的元素,并对其求和即可。

【代码实现】

#include int main() { int array[3][3]; int sumLT2RB = 0; // 标记左上角到右下角对角线元素之和 int sumRT2LB = 0; // 标记右上角到左下角对角线元素之和 printf("请输入3行3列的矩阵:\n"); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) scanf("%d", &array[i][j]); } // 左上角到右下角对角线 for (int i = 0; i < 3; ++i) sumLT2RB += array[i][i]; for (int i = 0, j = 2; i < 3; ++i, j--) sumRT2LB += array[i][j]; printf("左上角到右下角对角线元素之和: %d\n", sumLT2RB); printf("右上角到左下角对角线元素之和: %d\n", sumRT2LB); return 0; }

【结果截屏】

4. 有一个已经排好序的数组,要求输入一个数后,按原来顺序的规律将它插入数组中

【答案解析】

将数据插入到已排序的序列中,只需两步即可:

找待插入元素在数组中的插入位置 插入元素

具体如下:

注意:极端情况下,end可能会被减为-1,比如在上述序列中插入0

【代码实现】

#include int main() { int num = 0; int array[10] = {1,2,3,4,5,6,7,8,9}; printf("请输入一个整数:"); scanf("%d", &num); printf("原数组序列为:\n"); for (int i = 0; i < 9; ++i) printf("%d ", array[i]); printf("\n"); // 数组为升序 // 在数组中找待插入元素的位置,具体找的方式为: // 从后往前依次与数组中元素进行比较,如果要插入元素num比end位置数据小,则num一定插在end位置之前 // 因此将end位置数据往后搬移一个位置 // 如果num大于end位置元素或者end已经在区间最左侧,则位置找到 // 最后将新元素插入到end+1的位置 int end = 8; while (end >= 0 && num < array[end]) { array[end+1] = array[end]; end--; } array[end + 1] = num; printf("插入元素%d之后的结果为:\n", num); for (int i = 0; i < 10; ++i) printf("%d ", array[i]); printf("\n"); return 0; }

【结果截图】

5. 将一个数组中的值按逆序重新存放。例如:原来顺序为8,6,5,4,1。要求改为1,4,5,6,8。

【答案解析】

该题为数组的逆置,具体处理方式如下:

如果begin < end时,则循环进行一下操作

给定两个下标begin和end,begin放在数组起始的位置,end放在数组最后一个元素的位置 交换begin和end位置的元素 begin往后移动,end往前移动

【代码实现】

#include int main() { int array[5] = {8,6,5,4,1}; int begin = 0, end = 4; printf("逆序之前数组为:"); for (int i = 0; i < 5; ++i) printf("%d ", array[i]); printf("\n"); // 逆序:begin在数组最左侧,end在数组最右侧 // 只要begin < end,将begin和end位置元素进行交换 // 然后begin往后移动一步,end往前移动一步 while (begin < end) { int temp = array[begin]; array[begin] = array[end]; array[end] = temp; begin++; end--; } printf("逆置之后数组为:"); for (int i = 0; i < 5; ++i) printf("%d ", array[i]); printf("\n"); return 0; }

【结果截屏】

6. 输出一下的杨慧三角(要求输出10行) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 ……

【答案解析】

仔细观察杨慧三角可以看到:

第0列和对角线上的数据全部为1,其余位置上的数据为上一行正对数据与上一行正对前一个数据之和。

比如:a[4][2] = a[3][2] + a[3][1]

【代码实现】

#include int main() { int array[10][10]; for (int i = 0; i < 10; ++i) { for (int j = 0; j x ……

即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求编程序将密码译回原文,并输出密码和原文。

【答案解析】

从题目给的实例中可以看到,编码规则非常简单,就是将从前往后数的第i个字母转化为从后往前数的第i个字母。

那解压时直接反过来转换即可:

即'Z'--->'A' 'z'--->'a'

​ 'Y'--->'B' 'y'--->'b'

​ 'X'--->'C' 'x'--->'c'

假设如果当前拿到的是小写字母,转换方式如下:

先用s[i] - 'a'计算出s[i]是26个字母中从前往后数的第几个 再用26 - (s[i]- 'a') - 1 转换为26个字母中从后往前数的第几个 在2的结果上加上'a',即转换为对应从后往前的第几个字母

大写字母转换方式与上述相同,将上述每条中的'a'换为‘A’即可。

【代码实现】

#include int main() { char s[1024] = {0}; scanf("%s", s); int len = strlen(s); // 转换 for (int i = 0; i < len; ++i) { // 如果是小写字母(大写字母出来类似): // 1. 先用s[i] - 'a'计算出s[i]是26个字母中从前往后数的第几个 // 2. 再用26 - (s[i]- 'a') - 1 转换为26个字母中从后往前数的第几个 // 3. 在2的结果上加上'a',即转换为对应从后往前的第几个字母 if (s[i] >= 'a' && s[i] = 'A' && s[i] s2,输出一个整数;若s1 = s2,输出0;若s1 < s2,输出一个负数。不要用strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相对应字符的ASCII码的差值。例如,"A"和“C”相比,由于"A" < "C",应输出负数,同时由于‘A’与‘C’的ASCII码差值为2,因此应输出"-2"。同理:“And”和"Aid"相比较,根据第2个字符比较结果,"n"比"i"大5,因此应输出"5"。

【答案解析】

字符串比较规则:从前往后逐个字符进行比较,相等时继续往后,不相等时返回该位置两个字符差值。

【代码实现】

#include int main() { int ret = 0; int index = 0; char s1[100] = { 0 }; char s2[100] = { 0 }; printf("请输入s1:"); gets(s1); printf("请输入s2:"); gets(s2); // 将s1和s2中的字符从前往后逐个进行比较,相等继续往后, // 不相等时ret中结果不为0,!ret则为0 循环结束 // 如果一个走到末尾,一个未走到末尾 ret也不为0, !ret为0,循环结束 // 如果两个字符串相等,同时达到末尾,循环结束 while (!(ret = s1[index] - s2[index]) && '\0' != s1[index] && '\0' != s2[index]) { ++index; } printf("%d\n", ret); return 0; }

【结果截屏】

15. 编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中,不用strcpy函数。复制时,‘\0’也要赋值过去。'\0'之后的字符不复制。

【答案解析】

首先必须保证s1能否放的下s2中的字符,然后将s2中的每个字符逐个搬移到s1中即可。

【代码实现】

#include int main() { char s1[100] = { 0 }; char s2[50] = { 0 }; int index1 = 0, index2 = 0; printf("请输入字符串s2:"); scanf("%s", s2); printf("将s2拷贝到s1中, s1现在为: "); // 将s2[index2]位置字符拷贝到s1[index]位置, // 然后以s1[index1]的值作为循环条件判断是否拷贝到s2的末尾 while (s1[index1++] = s2[index2++]); printf("%s\n", s1); return 0; }

【结果截屏】

c语言程序设计第五版课后答案谭浩强更多答案

c语言程序设计第五版课后答案谭浩强 第五章课后答案 c语言程序设计第五版课后答案谭浩强 第七章课后答案



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3