CodeSky 代码之空

随手记录自己的学习过程

C 打印输入中单词长度的直方图

2014-02-21 19:28分类: C评论: 0

导言中的题目,昨天我勉强算实现了输出,不过效果其实很糟糕,还是没有考虑今天发的那几个问题,下载好答案之后就看了看,题目意思也明白了:

原话:

编写一个程序,打印输入中单词长度的直方图。水平方向的直方图比较容易,垂直方向的直方图则要困难一些。

实际上,他是要统计,比如hello有5个字母,我只输入hello 那么5中就输出1,类似的hello world在5中就输出2

我当时实际上只是很简单的直方图了,而没有考虑本身,所以是个错误的答案。

同时我还在想,我怎么知道单词有多长呢——答案很好的解决了这个问题。

基本的内容我都加了注释了。

水平直方图:

1#include <stdio.h>
2
3#define MAXHIST 15  // 直方图的最大长度
4#define MAXWORD 11  // 单词最大长度
5#define IN 1
6#define OUT 0
7
8main(void)
9{
10    int c, i, nc, state;
11    int len;        // 每个直方长度
12    int maxvalue;    // 单词的最大值
13    int ovflow;     //  溢出单词的个数
14    int wl[MAXWORD]; // 单词长度统计
15
16    state = OUT;
17    nc = 0;         // 单词中的字符数;
18    ovflow= 0;     // 单词 >= 最大单词 的个数
19    for (i = 0; i < MAXWORD; ++i)
20        wl[i] = 0;  // 设定初值
21    while ((c = getchar()) != EOF) {
22        if (c == ' ' || c == '\n' || c == '\t') {
23            state = OUT;
24            // 单词结束 开始统计字符数
25            if (nc > 0)
26                if (nc < MAXWORD)
27                    ++wl[nc];
28                else
29                    ++ovflow;
30            nc = 0;
31        } else if (state == OUT) {
32            state = IN;
33            nc = 1;     // 新的一个单词开始计数
34        } else
35            ++nc;       // 单词计数
36    }
37    // 找出最大值
38    maxvalue = 0;
39    for (i = 1; i < MAXWORD; ++i)
40        if (wl[i] > maxvalue)
41            maxvalue = wl[i];
42
43    for (i = 1; i < MAXWORD; ++i) {
44        printf("%5d - %5d : ", i, wl[i]);   // 字符数 - 单词个数
45        if (wl[i] > 0) {
46            // 1 设定len的长度 2 如果len存在但过小会被舍去小数部分,故判断手动改为1
47            if ((len = wl[i] * MAXHIST / maxvalue) <= 0)
48                len = 1;
49        } else
50            len = 0;    // 如果遍历时为0
51        while (len > 0) {
52            putchar('*');   // 用 * 占位
53            --len;
54        }
55
56        putchar('\n');
57    }
58
59    // 对超过限值的单词进行报告
60    if (ovflow > 0)
61        printf("There are %d words >= %d\n", ovflow, MAXWORD);
62}
63

竖直直方图(其实还是横着一个个输出的):

1#include <stdio.h>
2
3#define MAXHIST 15
4#define MAXWORD 11
5#define IN 1
6#define OUT 0
7
8main(void)
9{
10    int c, i, j, nc, state;
11    int maxvalue;       // 数组wl[]的最大值
12    int ovflow;         // 超过最大长度的单词书
13    int wl[MAXWORD];    // 单词长度计数
14
15    state = OUT;
16    nc = 0;             // 一个单词中的字符数量
17    ovflow = 0;         // words >= MAXWORD 的数量
18    for (i = 0; i < MAXWORD; ++i)
19        wl[i] = 0;      // 给单词长度设定初值
20    while ((c = getchar()) != EOF) {
21        if (c == ' ' || c == '\n' || c == '\t') {
22            state = OUT;
23            if (nc > 0)
24                if (nc < MAXWORD)
25                    ++wl[nc];
26                else
27                    ++ovflow;
28            nc = 0;
29        } else if (state == OUT) {
30            state = IN;
31            nc = 1;
32        } else
33            ++nc;
34    }
35    maxvalue = 0;
36    for (i = 1; i < MAXWORD; ++i)
37        if (wl[i] > maxvalue)
38            maxvalue = wl[i];
39
40    for (i = MAXHIST; i > 0; --i) {     // 列数(从最大依次递减)
41        for (j = 1; j < MAXWORD; ++j)   // 行数
42        // i从最大值开始 如果满足这一行条件(> i) 则输出 * MAXHIST / maxvalue相当于设定百分比
43            if (wl[j] * MAXHIST / maxvalue >= i)
44                printf("%4c", '*');
45            else
46                printf("%4c", ' ');
47            putchar('\n');
48    }
49    for (i = 1; i < MAXWORD; ++i)
50        printf("%4d", i);
51    putchar('\n');
52    for (i = 1; i < MAXWORD; ++i)
53        printf("%4d", wl[i]);
54    putchar('\n');
55    if (ovflow > 0)
56        printf("There are %d words >= %d\n", ovflow, MAXWORD);
57
58    return 0;
59}
60

注释部分看完水平再看竖直基本上就能明白整个程序什么意思了,竖直方向可以看成是一个直角坐标系。printf("%4c", '*');原来的答案并非这么写,而是用空格填满,可是- -不晓得多少个空格我对不准…………

评论 (0)