再读《The C Programming Language》 - 第一章 1.6 数组

本文介绍C语言中数组的基本概念,并通过实例演示如何使用数组统计字符频率及绘制单词长度直方图。

1.6 数组

这节开始讲数组了,比较简单、轻松的引入了数组的的概念,确实这里没有必要讲的那么复杂基于前面的基础,举了一个简单的例子;但练习题就有点难度了。

#include <stdio.h>  /* 头文件 */
#include <stdlib.h>


/* count digits, white space, others */
int main()
{
    int c, i, nwhite, nother;
    int ndigits[10];

    nwhite = nother = 0;
    for(i = 0; i < 10; i++)
        ndigits[i] = 0;

    while((c = getchar()) != EOF)
    {
        if( c >= '0' && c <= '9')   /* 字符0-9 处理很巧妙 */
            ++ndigits[c - '0'];
        else if ( c == ' ' || c == '\n' || c == '\t' )
            ++nwhite;
        else
            ++nother;
    }
    printf("digits =");
    for ( i = 0; i < 10; ++i )
        printf("%4d", ndigits[i]);
    printf(",white = %d, others = %d\n", nwhite, nother);

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}


Exercise 1-13. Write a program to print a histogram of the lengths of words in its input. It is easy to draw the histogram with the bars horizontal; a vertical orientation is more challenging.
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define MAX_WORDS       80      /* 一般DOS界面宽度为80 */
#define MAX_WORD_LENS   20      /* 最大单词长度 */

#define MARKED          1
#define NO_MARKED       0

#define BAR             '+'     /* 直方图符号 */

/* Print words lengths */
int main()
{
    int c;

    int nwords, nwordlens;
    int state;
    int word_lens[MAX_WORDS] = {0};

    int i, j;

    nwords = nwordlens = 0;
    state = NO_MARKED;

    while ( (c = getchar()) != EOF )
    {
        if ( c == ' ' || c == '\t' || c == '\n' )
        {
            if ( state == MARKED )
            {
                state = NO_MARKED;
                word_lens[nwords] = nwordlens;
                nwordlens = 0;
                ++nwords;
                if( nwords >= MAX_WORDS)
                    break;

            }
        }
        else
        {
            state = MARKED;
            ++nwordlens;
        }
       
    }

    // draw the histogram with the bars horizontal
    for ( i = 0 ; i < MAX_WORDS; i++ )
    {
        printf( "%2d : |",i );
        for( j = 0; j < word_lens[i]; j++)
            putchar(BAR);
        printf("\n");
    }

    // draw the histogram with the bars vertical
    for ( i = 0;  i < MAX_WORDS; i++)
        putchar('=');

    // draw cut-off rule
    for ( i = MAX_WORD_LENS; i > 0; i-- )
    {
        for ( j = 0; j < MAX_WORDS; j++ )
            if ( i <= word_lens[j] ) 
                putchar(BAR);
            else
                putchar(' ');
    }

    // draw cut-off rule
    for ( i = 0;  i < MAX_WORDS; i++)
        putchar('-');

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

这个基于现在已有的知识暂且这么写了,当C学的更加深入,我们再回头来改写这个程序,应该可以写的更好;
程序中两点说明下:定义了两个最大限制,限制了最大输入单词数量为80个,每个单词最长为20个字符,这个应该算把大事化小吧!我也不会处理无穷量,再说计算机的资源也是有限的。单词数量为80,是基于一般DOS窗口横向为80个字符,这样打印垂直方向的直方图就好处理些。

Exercise 1-14. Write a program to print a histogram of the frequencies of different characters in its input. 
大家可以查看ASCII 字符表 可以发现所有的字符,应该是从 “空格”(32) 到 “~”(126)结束,一共 126-32 = 94个,而且是连续的,所以可以根据本小节例题的例子来写这个程序,代码如下:

#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define START           ' '
#define END             '~'
#define MAX_CHAR        END - START + 1
#define HORIZONTAL_BUF  80  
#define BAR             '+'    

/* count digits, white space, others */
int main()
{
    int c, i, j;
    int nchars[MAX_CHAR];

    // initial nchars as 0
    for(i = 0; i < MAX_CHAR; i++)
        nchars[i] = 0;

    while((c = getchar()) != EOF)
    {
        if( c >= START && c <= END )   /* 仿效例子中字符0-9 处理的巧妙 */
            ++nchars[c - START];
    }
    
    // draw cut-off rule 
    for ( i = 0;  i < HORIZONTAL_BUF; i++)
        putchar('-');

    // draw the histogram with the bars horizontal
    for ( i = 0; i < MAX_CHAR; i++ )
    {
        printf( "%c : |",i + START );
        for( j = 0; j < nchars[i]; j++)
            putchar(BAR);
        printf("\n");
    }
    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}








评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值