第1章-导言-习题1.13-1.23

1-13

先放上自己写的程序,不论是打印水平方向的直方图还是垂直方向的直方图,前提都是先得到单词的长度,然后将该长度在数组nlenth[]对应的元素加1,也就说统计不同长度出现的次数。

 1 #include<stdio.h>
 2
 3 #define IN 1
 4 #define OUT 0
 5 #define MAXSIZE 10
 6
 7 /* 16/06/09 打印输入中单词长度的直方图 */
 8 main()
 9 {
10     char state = OUT;
11     char c,i;
12     int nlength[MAXSIZE];
13     char nword = 0;
14
15     for (i = 0; i < MAXSIZE; i++) {
16         nlength[i] = 0;
17     }
18     while ((c = getchar()) != EOF) {
19         if (c == ‘ ‘ || c == ‘\t‘ || c == ‘\n‘) {
20             state = OUT;
21         }
22         else if (state == OUT) {
23             state = IN;
24         }
25         while (state == IN) {
26             nword++;
27             c = getchar();
28             if (c == ‘ ‘ || c == ‘\t‘ || c == ‘\n‘) {
29                 state = OUT;
30                 nlength[nword]++;
31                 nword = 0;
32             }
33         }
34     }
35     /* 绘制水平方向直方图 */
36     /*
37     for (i = 0; i < MAXSIZE; i++) {
38         printf("%d ", i);
39         for (j = 0; j < nlength[i]; j++) {
40             putchar(‘*‘);
41         }
42         putchar(‘\n‘);
43     }
44     */
45     /* 绘制垂直方向直方图,思路仍是一行行输出 */
46     int ncopy[MAXSIZE];
47     int ln, k, kmax;
48     /* 下面这一段代码是求数组nlength[]中的最大值 */
49     for (ln = sizeof(nlength) / sizeof(int), k = kmax = 0; k < ln; k++) {
50         if (nlength[kmax] < nlength[k])
51             kmax = k;
52     }
53     for (i = 0; i < MAXSIZE; i++) {
54         ncopy[i] = nlength[i];
55         printf("%d ", i);
56     }
57     putchar(‘\n‘);
58     for (k = 0; k < kmax; k++) {
59         for (i = 0; i < MAXSIZE; i++) {
60             if (ncopy[i] > 0) {
61                 putchar(‘*‘);
62                 putchar(‘ ‘);
63                 ncopy[i]--;
64             }
65             else {
66                 putchar(‘ ‘);
67                 putchar(‘ ‘);
68             }
69         }
70         putchar(‘\n‘);
71     }
72
73 }

1-13.c

打印水平方向的直方图容易点,运行结果如下(注意输入完毕后先Enter再Ctrl+Z)

接下来是绘制垂直方向的直方图,写的稍微费事了一些,思路是先找到数组nlength[]中的最大值,在一次性输出0-9的过程中将数组nlength复制到另一个数组ncopy(否则后面的自减会丢失),然后根据相应数目输出*。

答案的前提和我的相同,也需要统计不同长度出现的次数,不过引入了overflow来统计超出允许最大长度的单词个数。

对于水平直方图(程序为1-13-a1.c),答案额外写了一段代码来找到统计到的长度数值中的最大值,以此来计算wl[i]对应的直方图长度(我的是有多少就输出多少*),计算公式是len=wl[i]*MAXHIST/maxvalue,我觉得采取这个公式只是起到计算的作用,没有特殊意义。

 1 #include<stdio.h>
 2
 3 #define IN 1
 4 #define OUT 0
 5 #define MAXSIZE 10
 6 #define MAXHIST 15
 7
 8 /* 16/06/15 打印输入单词长度的水平直方图 */
 9 main()
10 {
11     char state = OUT;
12     char c, i;
13     int nlength[MAXSIZE];
14     int len;
15     int nc, overflow;
16     int maxvalue;
17
18     nc = 0;
19     overflow = 0;
20     for (i = 0; i < MAXSIZE; i++) {
21         nlength[i] = 0;
22     }
23     while ((c = getchar()) != EOF) {
24         if (c == ‘ ‘ || c == ‘\t‘ || c == ‘\n‘) {
25             state = OUT;
26             if (nc > 0) {
27                 if (nc<MAXSIZE)
28                     ++nlength[nc];
29                 else ++overflow;
30             }
31             nc = 0;
32         }
33         else if (state == OUT) {
34             state = IN;
35             nc = 1;
36         }
37         else nc++;
38     }
39     /* 绘制水平方向直方图 */
40     maxvalue = 0;
41     for (i = 1; i < MAXSIZE; i++) {
42         if (maxvalue < nlength[i])
43             maxvalue = nlength[i];
44     }
45     for (i = 1; i < MAXSIZE; i++) {
46         printf("%d - %d : ", i, nlength[i]);
47         if (nlength[i] > 0) {
48             if ((len = nlength[i] * MAXHIST / maxvalue) <= 0)
49                 len = 1;
50         }
51         else len = 0;
52         while (len--)
53             putchar(‘*‘);
54         putchar(‘\n‘);
55     }
56     if (overflow > 0)
57         printf("There are %d words >= %d\n", overflow, MAXSIZE);
58
59 }

1-13-a1.c

运行效果如下:

1-13-a2是绘制垂直直方图,

 1 #include<stdio.h>
 2
 3 #define IN 1
 4 #define OUT 0
 5 #define MAXSIZE 10
 6 #define MAXHIST 15
 7
 8 /* 16/06/15 打印输入单词长度的垂直直方图 */
 9 main()
10 {
11     char state = OUT;
12     char c, i, j;
13     int nlength[MAXSIZE];
14     int nc, overflow;
15     int maxvalue;
16
17     nc = 0;
18     overflow = 0;
19     for (i = 0; i < MAXSIZE; i++) {
20         nlength[i] = 0;
21     }
22     while ((c = getchar()) != EOF) {
23         if (c == ‘ ‘ || c == ‘\t‘ || c == ‘\n‘) {
24             state = OUT;
25             if (nc > 0) {
26                 if (nc<MAXSIZE)
27                     ++nlength[nc];
28                 else ++overflow;
29             }
30             nc = 0;
31         }
32         else if (state == OUT) {
33             state = IN;
34             nc = 1;
35         }
36         else nc++;
37     }
38     /* 绘制水平方向直方图 */
39     maxvalue = 0;
40     for (i = 1; i < MAXSIZE; i++) {
41         if (maxvalue < nlength[i])
42             maxvalue = nlength[i];
43     }
44     for (i = MAXHIST; i > 0; i--) {                        //之所以是从MAXHIST开始是为了从底部开始显示*,看一下运行结果就知道了
45         for (j = 1; j < MAXSIZE; j++) {
46             if ((nlength[j] * MAXHIST / maxvalue) >= i)
47                 printf(" * ");
48             else
49                 printf("   ");
50
51         }
52         putchar(‘\n‘);                                    //注意这一句是必须写的
53     }
54     for (i = 1; i < MAXSIZE; i++)
55         printf(" %d ", i);
56     putchar(‘\n‘);
57     for (i = 1; i < MAXSIZE; i++)
58         printf(" %d ", nlength[i]);
59     putchar(‘\n‘);
60     if (overflow > 0)
61         printf("There are %d words >= %d\n", overflow, MAXSIZE);
62
63 }

1-13-a2.c

运行效果如下,

1-14

我仅仅是在教材P15例程基础上稍作改动,根据统计到的ndigit[i]、nwhite、nother打印相应数目的*,

 1 #include<stdio.h>
 2
 3 /* 16/06/09 打印输入中各个字符出现频度的直方图 */
 4 main()
 5 {
 6     char c, i, j,nwhite, nother;
 7     int ndigit[10];
 8
 9     nwhite = nother = 0;
10     for (i = 0; i < 10; i++) {
11         ndigit[i] = 0;
12     }
13     while ((c = getchar()) != EOF) {
14         if (c >= ‘0‘&&c <= ‘9‘)
15             ++ndigit[c - ‘0‘];
16         else if (c == ‘ ‘ || c == ‘\t‘ || c == ‘\n‘)
17             ++nwhite;
18         else ++nother;
19     }
20     /* 绘制水平方向直方图 */
21     for (i = 0; i < 10; i++) {
22         printf("%d     ", i);
23         for (j = 0; j < ndigit[i]; j++) {
24             putchar(‘*‘);
25         }
26         putchar(‘\n‘);
27     }
28
29     printf("white ");
30     for (i = 0; i < nwhite; i++) putchar(‘*‘);
31     putchar(‘\n‘);
32
33     printf("other ");
34     for (i = 0; i < nother; i++) putchar(‘*‘);
35     putchar(‘\n‘);
36
37 }

1-14.c

答案能够处理的字符是ASCII字符集范围内的字符,因而设置了#define MAXCHAR 128,在这个宏定义的范围内,++cc[c]。

 1 #include<stdio.h>
 2 #include<ctype.h>
 3
 4 #define MAXCHAR 128
 5 #define MAXHIST 15
 6
 7 /* 16/06/15 打印输入中各个字符出现频度的直方图 */
 8 main()
 9 {
10     int c, i;
11     int len;
12     int maxvalue;
13     int cc[MAXCHAR];
14
15     for (i = 1; i < MAXCHAR; i++) {
16         cc[i] = 0;
17     }
18     while ((c = getchar()) != EOF) {
19         if (c < MAXCHAR) {
20             ++cc[c];
21         }
22     }
23     /* 绘制水平方向直方图 */
24     maxvalue = 0;
25     for (i = 1; i < MAXCHAR; i++) {
26         if (maxvalue < cc[i])
27             maxvalue = cc[i];
28     }
29     for (i = 1; i < MAXCHAR; i++) {
30         if (isprint(i))
31             printf("%5d - %c - %5d : ", i, i, cc[i]);
32         else
33             printf("%5d -   - %5d : ", i, cc[i]);
34         len = cc[i];                                    //还是直接让len=cc[i],好理解一些,下面的代码也只是输出cc[i]的倍数而已
35         /*
36         if (cc[i] > 0) {
37             if ((len = cc[i] * MAXCHAR / maxvalue) <= 0)
38                 len = 1;
39         }
40         else len = 0;
41         */
42         while (len > 0) {
43             putchar(‘*‘);
44             --len;
45         }
46         putchar(‘\n‘);
47     }
48
49 }

1-14-a.c

注意后面的输出格式设置,如果是ASCII字符集范围内的字符就显示出来,否则打印空白,

1 if (isprint(i))
2     printf("%5d - %c - %5d : ", i, i, cc[i]);
3 else
4     printf("%5d -   - %5d : ", i, cc[i]);

运行结果如下

1-15

比较简单,但是我的程序比较糟糕的一点是在函数Fahr_to_Cel内使用了printf,感觉独立性差了点,

 1 #include<stdio.h>
 2
 3 #define LOWER 0
 4 #define UPPER 300
 5 #define STEP 20
 6
 7 void Fahr_to_Cel(int lower, int upper, int step);
 8
 9 /*  16/06/09 温度转换程序 */
10 main()
11 {
12     Fahr_to_Cel(LOWER, UPPER, STEP);
13 }
14
15 void Fahr_to_Cel(int lower, int upper, int step)
16 {
17     int fahr, celsius;
18
19     for (fahr = lower; fahr <= upper; fahr += step) {
20         celsius = 5 * (fahr - 32) / 9;
21         printf("%d\t%d\n", fahr, celsius);
22     }
23 }

1-15.c

下面给出参考答案程序,

 1 #include<stdio.h>
 2
 3 #define LOWER 0
 4 #define UPPER 300
 5 #define STEP 20
 6
 7 float Fahr_to_Cel(float fahr);
 8
 9 /* 16/06/15 温度转换程序  */
10 main()
11 {
12     float fahr;
13     for (fahr = LOWER; fahr < UPPER; fahr += STEP) {
14         printf("%3.0f %6.1f\n",fahr,Fahr_to_Cel(fahr));
15     }
16 }
17
18 float Fahr_to_Cel(float fahr)
19 {
20     return (5.0 / 9.0)*(fahr - 32.0);
21 }

1-15-a.c

时间: 2024-08-15 07:36:12

第1章-导言-习题1.13-1.23的相关文章

第1章-导言-习题1.8-1.12

前面习题比较简单,根据教材就可以做出来,下面记录从习题1.8开始. 1.8 1 #include<stdio.h> 2 3 /* 16/6/8 count blanks,tabs,and newlines*/ 4 main() 5 { 6 int c, num_blank, num_tab, num_new; 7 8 num_blank = num_tab = num_new = 0; 9 while ((c = getchar()) != EOF) { 10 if (c == ' ') nu

《鸟哥linux》--第十一章课后习题答案

1.在linux上可以找到哪些shell?哪个档案记录可用的shell?儿linux预设的shell是? 1./bin/bash,/bin/tcsh,/bin/csh 2./etc/shells 3.bash,亦即是/bin/bash 2.在shell环境下,有个提示符(prompt),他可以修改吗?要改什么?默认的提示符内容是? 可以修改,改PS1变量,这个PS1的变量默认的内容为:[\[email protected]\h\W]\$ 3.如何显示HOME这个变量 echo $HOME 4.如

Python编程快速上手-让繁琐工作自动化 第三章 函数习题及其答案

第三章 函数习题及其答案 1.为什么在程序中加入函数会有好处? 答:函数减少了重复的代码.这让程序更短,更容易阅读,更容易修改. 2.函数中的代码何时执行: 在函数被定义时,还是在函数被调用时? 答:函数中的代码在函数被调用时执行,而不是在函数定义时. 3.什么语句创建一个函数? 答:def语句定义了(创建了)一个函数. 4.一个函数和一次函数调用有什么区别? 答:函数包含def语句和在def子句中的代码.函数调用让程序执行转到函数内,函数调用求值为该函数的返回值. 5.Python程序中有多少

《Cracking the Coding Interview》——第18章:难题——题目13

2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3)级别的时间和空间进行动态规划.这道题目和第17章的最后一题很像,由于这题的时间复杂度实在是高,我动手写了字典树进行加速.如果单纯用哈希表来作为词典,查询效率实际会达到O(n)级别,导致最终的算法复杂度为O(n^4).用字典树则可以加速到O(n^3),因为对于一个字符串"abcd",只需要

C++ Primer 第四版课后练习解答 习题1.13

注意:本随笔是直接参考<C++Primer(第四版)习题解答(完整版)>中的.此处主要是便于本人以后反复阅读. 习题1.13 编译器不同,理解其诊断内容的难易程度也不同.编写一些程序,包含本小节"再谈编译"部分讨论的那些常见错误.研究编译器产生的信息,这样你在编译更复杂的程序遇到这些信息时不会陌生. [解答] 对于程序中出现的错误,编译器通常会给出简略的提示信息,包括错误出现的文件及代码行.错误代码.错误性质的描述.如果要获得关于错误的详细信息,一般可以根据编译器给出的错误

C Primer Plus 第十二章课后习题……2015.5.10

第十二章课后习题 1.自动存储 寄存器存储 静态空连接 2.静态空连接 内部链接 外部链接 3.静态外部链接  静态内部链接 4.空连接 5.在声明中使用表面这个变量或函数已经定义过 6.都分配一个具有100个int值的数组,calloc还把每个元素设置为零. 7.daisy全局变量  lily局部变量 8.#include<stdio.h> char color='B'; void first(void); void second(void); int main(void) { extern

第七章 课后习题P206

第七章 课后习题P206 原文地址:https://www.cnblogs.com/chouqiuqiu/p/8857920.html

《计算机网络&amp;#183;自顶向下方法》第七版 第三章 课后习题与问题 答案

非官方答案,本人已尽最大努力(包括参考官方答案),使结果正确,如有错误,请大佬指出 正文: 3.1~3.3节 R1 a.如果只是简单想把信件送到,那么所有的头部信息只需要一个目的地址就够了,题目给出端口号四个字节,所有分组的头部那就只需四个字节 此协议规定,运输层的全部任务就是,将应用层的数据,切成最大1196字节的块,把每一块加上目的主机对应程序的端口号,并将得到的分组交付给网络层 在接收方,运输层将网络层报文取回,去掉头部信息,将数据拼接成应用层需要的信息,根据端口号交付给应用层即可 不过话

C primer 第六章习题6.13

//编写程序包含8个元素的int类型数组,用for循环设置数组元素,用do while循环显示元素值. #include <stdio.h>int main(void){       int num[8],index,i,pow; for (index=0,i=0,pow=1;index<=7;index++){                pow*=2;                num[index]=pow;            do    {            i++;