码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-07-31 12:58:09      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

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

 

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

标签:

原文地址:http://www.cnblogs.com/custalex/p/5722699.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!