失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言程序设计(第五版)谭浩强著 第6章习题答案

C语言程序设计(第五版)谭浩强著 第6章习题答案

时间:2019-01-16 00:25:16

相关推荐

C语言程序设计(第五版)谭浩强著 第6章习题答案

1.用筛选法求100之内的素数。

解题思路:

素数:在大于1的自然数中,只有1和它本身两个因数的数。

筛选法:古希腊数学家埃拉托色尼在纸上写下1-1000,逐一判断它们是否为素数,若不是则划去,最终留下的数必定为素数,这个方法成为”埃拉托色尼筛法“。

本题思路:(1)筛除1。(1必定不是素数)

(2)记第一个未被筛除的数字为m,用m后面的所有数除以m,若余数为0,则筛除。(筛 出m的倍数)

(3)检查m是否小于,若是则返回(2)继续执行,否则结束。

(4)剩下的数字为素数。

代码:

#include<stdio.h>#include<math.h>int main(){int i, j, n, a[101];for (i = 1; i <= 100; i++)//赋值,弃用a[0],a[1]=1,a[2]=2...a[100]=100a[i] = i;a[1] = 0; //若a[i]为非素数,则把a[i]赋值为0; 1必定不是素数for(i = 2; i < sqrt(100); i++) //筛选法,使得所有非素数a[i]=0for (j = i + 1; j <= 100; j++) {if (a[i] != 0 && a[j] != 0) {if (a[j] % a[i] == 0)a[j] = 0;}}for (i = 1, n=0; i <= 100; i++) {//控制输出if (a[i] != 0) {printf("%d\t", a[i]);n++;}if (n == 5) {printf("\n");n = 0;}}return 0;}

运行结果:

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

解题思路:

将10个数字存放在数组a[10]中,循环处理9趟,每次从剩下的数中选出最小的数放入a[i](i从0~9)

第1趟:用a[0]分别和a[1]~a[9]比较,若a[0]比a[1]~a[9]都小,则不进行交换;若a[1]~a[9]中有元素 小于a[0],则把小于a[0]的元素中最小的那个与a[0]交换。

第2趟:用a[1]分别和a[2]~a[9]比较,若a[1]比a[2]~a[9]都小,则不进行交换;若a[2]~a[9]中有元素 小于a[1],则把小于a[1]的元素中最小的那个与a[1]交换。

第3趟:用a[2]分别和a[3]~a[9]比较,若a[2]比a[3]~a[9]都小,则不进行交换;若a[3]~a[9]中有元素 小于a[2],则把小于a[2]的元素中最小的那个与a[2]交换。

.

.

.

第9趟:用a[8]和[9]比较,若a[8]小于a[9],则不进行交换;若a[8]大于a[9],则交换a[8]和a[9]。

代码:

#include<stdio.h>int main() {int i, j, t, min, a[10];for (i = 0; i < 10; i++)scanf_s("%d", &a[i]);for (i = 0; i < 9; i++) {//循环9次,每次选出一个最小的数,放到a[i]中(i从0~9)min = i; //用min记录最小数字的下标for (j = i + 1; j < 10; j++) { //从剩下的数字中选出最小的那个,将其下标赋值给minif (a[j] < a[min])min = j;}if (min != i) { t = a[min];a[min] = a[i];a[i] = t;}}printf("排序结果如下:\n");for (i = 0; i < 10; i++)printf("%4d", a[i]);printf("\n");return 0;}

运行结果:

3.求一个3*3的整形矩阵对角线元素之和。

解题思路:

定义一个整形二位数组a[3][3],分别输入个元素的个数,对角线元素和sum=a[0][0]+a[1][1]+a[2][2]。

代码:

#include<stdio.h>int main() {int i, j, sum, a[3][3];for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)scanf_s("%d", &a[i][j]);printf("该矩阵为:\n");for (i = 0; i < 3; i++) {for (j = 0; j < 3; j++)printf("%2d", a[i][j]);printf("\n");}sum = a[0][0] + a[1][1] + a[2][2];printf("该矩阵对角线元素和为:%d", sum);}

运行结果:

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

解题思路:

假设该数组长度为10,10个数字按照递增顺序分别存放在a[0]~a[9]中,待插入的数字为m。

将a[9]和m比较,a[9]小于m,则将m赋值给a[10];否则在a[0]~a[9]中找到第一个大于m的元素(假设为a[i]),将a[i]~a[9]中的值都后移一位,将m赋值给a[i]。

代码:

#include<stdio.h>int main() {int i = 0, m = 0, j, a[11] = { 1,3,5,6,7,9,12,16,30,42 }; //假设数组a中存放10个数字且递增有序printf("初始数组为:\n");for (j = 0; j < 11; j++)printf("%d\t",a[j]);printf("\n");printf("请输入想插入数字:");scanf_s("%d", &m);if (m > a[9]) //若m大于有序数组中的最大数,则将其插入数组末尾即可a[10] = m; else {while (a[i] < m) //找到第一个大于m的元素i++;for (j = 9; j >= i; j--)a[j + 1] = a[j];a[i] = m;}printf("插入%d后数组为:\n",m);for (j = 0; j < 11; j++)printf("%d\t", a[j]);return 0;}

运行结果:

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

解题思路:

以中间元素为中心,将其两侧对称的元素的值互换,具体如下:

假设a[5]中按递减顺序分别存放了8,6,5,4,1。

设置两个变量i,j初值分别等于0和4;

当i小于5/2时,交换a[i]和a[j]的值,然后i加1,j减1。

代码:

#include<stdio.h>int main() {int i, j, t, a[5] = { 8,6,5,4,1 };printf("数组a的初始值为:\n");for (i = 0; i < 5; i++)printf("%3d", a[i]);printf("\n");for (i = 0, j = 4; i < 5 / 2; i++, j--) {t = a[i];a[i] = a[j];a[j] = t;}printf("经过逆置操作后,数组a的值为:\n");for (i = 0; i < 5; i++)printf("%3d", a[i]);return 0;}

运行结果:

6.输出以下的杨辉三角形(要求输出10行)。

解题思路:

杨辉三角形有以下规律(见下图):

(1)每行第一个数和最后一个数均为1。

(2)从第3行起,除(1)中所提的数外,其余数 等于上一行同列数字和前一列数字之和。

代码:

#include<stdio.h>int main() {int i, j, a[10][10]; //输出10行for (i = 0; i < 10; i++) { //使得每行的第一个和最后一个元素为1a[i][0] = 1;a[i][i] = 1;}for (i = 2; i < 10; i++) //其余元素等于上一行同列数字和前一列数字之和for (j = 1; j < i; j++)a[i][j] = a[i - 1][j] + a[i - 1][j - 1];for (i = 0; i < 10; i++) { //控制输出for (j = 0; j <= i; j++)printf("%-5d", a[i][j]);printf("\n");}return 0;}

运行结果:

7.输出”魔方阵“。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。例如,三阶魔方阵如下,要求输出1~n^2的自然数构成的魔方阵。

8 1 6

3 5 7

4 9 2

解题思路:

观察可得魔方阵中各数满足以下规律:

(1)1放在第1行中间一列。

(2)2~n*n存放规律为:每个数存放的行比上一个数的行数减1,列比上一个数的列数加1。

(3)若上一个数在第1行,则下一个数在第n行,列数同样加1。

(4)若上一个数在第n列,则下一个数在第1列,行数同样减1。

(5)若按以上规律确定的位置上已有数或上一个数为第1行第n列时,则把下一个数放在上一个数面。

代码:

#include<stdio.h>int main() {int i, j, k, n, a[15][15] = { 0 };printf("请输入阶数n(1~15的奇数):");scanf_s("%d", &n);while (n % 2 == 0||n<1||n>15) {printf("您输入的阶数不满足要求,请重新输入:");scanf_s("%d", &n);}i = 1; j = n / 2 + 1;a[i][j] = 1;//1放在第1行中间一列for (k = 2; k <= n * n; k++) {i -= 1;//行数减1j += 1;//列数加1if (i<1 && j>n) { //若前一个数在第1行第n列,则下一个数放在它下面i += 2;j = n;}else {if (i < 1) { //行特殊:若上一个数在第1行,则下一个数在第n行i = n;}if(j>n){ //列特殊:若上一个数在第n列,则下一个数在第1列j = 1;}}if (a[i][j] == 0) a[i][j] = k;else {//若按规则确定的位置上已有数字,则下一个数放在上一个数下面i += 2;j -= 1;a[i][j] = k;}}for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++)printf("%-5d", a[i][j]);printf("\n");}return 0;}

运行结果:

8.找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点。

解题思路:

循环遍历每一行,每次找出该行上最大的那个元素,遍历它所在的列,将它与该列上其他元素逐一比较,若它不是最小值,则它不是鞍点;若它为最小值,则它是鞍点,输出。

代码:

#include<stdio.h>#define m 4#define n 5int main() {int i, j, k, max, p=0, flag=0, a[m][n] = { 0 };printf("请输入数组的值:\n");for (i = 0; i < m; i++)//输入数组for (j = 0; j < n; j++)scanf_s("%d", &a[i][j]);for (i = 0; i < m; i++) { //循环遍历每一行max = a[i][0];for (j = 1; j < n; j++) { //找到第i行中,最大的元素,把它的列下标暂存pif (a[i][j] > max)p = j;}for (k = 0; k < n; k++) { //循环遍历第p列,若有元素小于a[i][p]则跳出循环if (a[k][p] < a[i][p])break;//结束内循环}if (k == n - 1) {//若遍历完第p列,所有元素都大于或等于a[i][p]则a[i][p]为鞍点flag = 1;printf("a[%d][%d]=%d为鞍点", i, p, a[i][p]);}if (flag == 1)//一个二位数组最多只有一个鞍点,若找到一个鞍点,则用brek结束外层循环break;}if(flag==0)printf("该数组没有鞍点!\n");return 0;}

运行结果:

9.有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“无次数”。

解题思路:

折半查找法的基本思想是将查找区间不断折半,以缩小查找范围,直到找到目标元素或者查找区间为空为止。

本题具体思路如下:

(1)设置两个整形变量low、high分别等于0和14;

(2)变量mid=(low+high)/2,将a[mid]和输入的数字x比较;

(3)若a[mid]>x,则令low等于mid+1,返回(2)在右边一半区间内继续查找;

(4)若a[mid]<x,则high等于mid-1,返回(2)在左边一半区间内继续查找;

(5)若a[mid]==x,则输出mid+1,循环结束;

(6)重复以上步骤直到目标元素或查找区间为空为止。

代码:

int main() {int low, high, mid, x, a[15] = { 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 };printf("请输入您要查找的数字:");scanf_s("%d", &x);low = 0;high = 14;while (low <= high) {mid = (low + high) / 2;if (a[mid] == x) {printf("该数是数组中的第%d个数", mid + 1);break;}else if (a[mid] > x) low = mid + 1;else high = mid - 1;}return 0;}

运行结果:

10.有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数。

解题思路:

定义一个二维字符数组存放文章,依次读入每一个行的内容,并逐一判断该行每一个字符是否为英文大写字母、小写字母、数字、空格或其他,并将其对应的记录变量加1。

代码:

#include<stdio.h>int main() {int i, j, upp, low, dig, spa, oth;upp = low = dig = spa = oth = 0; //初值为0char a[3][80];for (i = 0; i < 3; i++) {printf("请输入文章第%d行的内容:\n",i+1);gets(a[i]); //读入第i行的内容for (j = 0; j < 80 && a[i][j] != '\0'; j++) {if (a[i][j] >= 'A' && a[i][j] <= 'Z')upp++;else if (a[i][j] >= 'a' && a[i][j] <= 'z')low++;else if (a[i][j] >= '0' && a[i][j] <= '10')dig++;else if (a[i][j] == ' ')spa++;elseoth++;}}printf("文中包含英文大写字母%d个,小写字母%d个;\n", upp, low);printf("包含数字%d个,空格%d个,其他字符%d个\n", dig, spa, oth);return 0;}

运行结果:

11.输出以下图案:

解题思路:

定义一个字符数组a[5]={”*****“},循环输出5行,每一行控制缩进和输出格式,详细请看代码注释。

代码:

#include<stdio.h>int main() {int i,j,k;char a[] = { "*****" };for (i = 0; i < 5; i++) { //外层循环控制输出5行for (k = 1; k <= i; k++) //内层循环控制每行的缩进printf(" ");for (j = 0; j < 5; j++) { //控制每一行的输出printf(" "); //每个星号前输出一个空格printf("%c", a[j]);//输出星号}printf("\n");//输出完一行后换行}return 0;}

运行结果:

12.有一行电文,已按下面规律译成密码:即第1个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。要求编程序将密码译为原文,并输出密码和原文。

解题思路:

定义一个字符数组a,用来存放电文,循环处理字符数组中的每一个元素a[j],若a[j]为字母则按照题目规律还原原来字母(具体思路如下),若它为非字母则直接输出。

若字符a[j]为大写字母,则它是26个字母中的第(a[j]-64)个大写字母(因为第一个字母'A'的ASCII码为65);此时根据密码规则,a[i]对应的密码为第 [ 26-(a[j]-64)+1 ]个字母,它的ASCII码为 { [ 26-(a[j]-64)+1 ]+64 } = 155-a[j]。因此当a[j]为大写字母时,它对应的原文为:155-a[j]

若字符a[j]为小写字母,则通过同样分析可得,它对应的原文为:219-a[j]

代码:

#include<stdio.h>#define m 50int main() {int i;char a[m] = { 0 };printf("请输入电文:");gets(a);printf("密码为:%s\n",a);for (i = 0; i < m && a[i] != '\0'; i++) {if (a[i] >= 'A' && a[i] <= 'Z')a[i] = 155 - a[i];else if (a[i] >= 'a' && a[i] <= 'z')a[i] = 219 - a[i];elsea[i] = a[i];}printf("原文为:%s\n",a);return 0;}

运行结果:

13.编一程序,将两个字符串连接起来,不要用strcat函数。

解题思路:

利用两个字符数组a[ ]、b[ ]分别存放两个字符串。

用整型变量i记录字符数组a中第一个字符串结束的位置,将第二个字符串从i开始存入字符数组a。

代码:

#include<stdio.h>int main() {int i=0, j;char a[50], b[50];printf("请输入第一个字符串:\n");gets(a);printf("请输入第二个字符串:\n");gets(b);while (a[i] != '\0') //用i记录字符串数组a的最后一个字符'\0'的下标i++;for (j = 0; b[j] != '\0'; i++,j++) { //将字符数组b连接在字符数组a后面a[i] = b[j];}a[i] = '\0'; //添加字符串结束标志'\0'printf("连接后字符串为:\n");printf("%s", a);return 0;}

运行结果:

14.编一个程序,将两个字符串s1和s2比较,若s1>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”。

解题思路:

用字符数组a和b分别存放两个字符串,循环将a中的元素逐一和b中的元素比较;

当a、b遇到第一个a[i]!=b[i]时,循环结束,输出a[i]-b[i]。

当a[i]=='\0'时,循环同样结束,此时判断(1)若a[i]和b[i]都为'\0',则说明两个字符串相等,输出0;

(2)若a[i]为'\0'而b[i]不为'\0',则说明b字符串长于a[i],输 出a[i]-b[i]

代码:

#include<stdio.h>int main() {int i = 0;char a[100], b[100];printf("请输入第一个字符串:\n");gets(a);printf("请输入第二个字符串:\n");gets(b);while ((a[i] == b[i]) && a[i] != '\0') //当第一个不相等字符出现或第一个字符串结束时,循环结束i++;if (a[i] == '\0' && b[i] == '\0') //若第一个字符串结束时,第二个字符串也结束,输出0printf("结果为:0\n");elseprintf("结果为:%d\n", a[i] - b[i]);return 0;}

运行结果:

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

解题思路:

由于要复制'\0',可采用strlen( )函数。利用for循环,逐一复制即可。

代码:

#include<stdio.h>int main() {int i = 0;char s1[50], s2[30];printf("请输入s2字符串:");gets(s2);for (i = 0; i <= strlen(s2); i++)s1[i] = s2[i];printf("s1字符串为:%s", s1);return 0;}

运行结果:

更多内容,关注我哦。

如果觉得《C语言程序设计(第五版)谭浩强著 第6章习题答案》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。