打印输入的单词长度和各个字符出现频数的直方图(水平方向和垂直方向)

       这事实上是K&R导言中练习1-13和1-14的问题,因为两个问题都涉及直方图,有些相似,所以都放在一起。相对来说自由发挥的余地比较大,不同的码者会写出不同形式的代码,下面只是我的解决方案。

#include <stdio.h>

#include <string.h>

#define MAXLINE 1000

//练习1-13 编写一个程序,能够打印输入中单词长度的直方图。【水平方向和垂直方向】

//当输入一个字符时,代表着计数加一,当输入碰到\n时,就把这个计数放到item里面,然后该计数重置为起始值,进行下一轮计数

//当碰到EOF时,计数结束,item会转化为条形统计图输出

int max(int a[MAXLINE],int item_length);

int main()

{                //用来存放每行的数组长度

    int item[MAXLINE];

    int i, it, j, c, count;

    it=count=0;

    while((c=getchar())!=EOF){

        ++count;

        if(c=='\n'){

            item[it]=count;

            ++it;

            count=0;

        }

    }

    //水平方向

    for(i=0;i<it;++i){

        printf("\n%c",124);//先打印竖线

        for(j=0;j<item[i];++j){    //横线

            printf("%c",95);

        }

        printf("\n%c",124);

        {for(j=0;j<item[i];++j){    //横线

            printf("%c",95);

        }

            printf("%c",124);//表格前端的竖线

            printf("%d",item[i]);//表格前面的数字

        }

    }

    printf("\n%c",124);

    //为了防止横坐标小于条形长度,需要自动对横坐标长度进行计算,比如最大条形长度的1.5

    //那么需要确定数组item中最大的数组长度,可以使用数组元素依次比较的方法

    for(i=0;i<max(item, it)*1.5;++i){

        printf("%c",95);

    }

        printf("\n");

    

    //垂直方向

    for(j=0;j<max(item,it)+2;++j){

        printf("\n%c",124);//纵坐标单位长度|

        for(i=0;i<it*2;++i){

            if(i%2!=0){

                if(max(item, it)-j+1<item[i/2]||max(item, it)-j+1<item[i/2+1]){

                    printf("%c",124);// 条形图边缘的|

                }

                else{

                    printf("%c",32);

                } //条形图外部上方

            }

            else{

                if(max(item, it)+2-j-item[i/2]==1){

                    printf("%c",95);//条形图上端

                }

                else if((j!=max(item,it)+1)&&(j!=max(item,it)+2)){

                    printf("%c",32);//条形图内部和上方为空

                }

                else{

                    printf("%c",95);//条形图下端

                }

            }

        }

    }

    for(i=0;i<4;++i){

        printf("%c",95);//横坐标增加4个长度

    }

    printf("\n");

}

int max(int a[MAXLINE],int item_length)

{

    int i,max_length;

    max_length=0;

    for(i=0;i<item_length;++i){

        if (a[i]>max_length)

            max_length=a[i];

    }

    return max_length;

}

运行结果测试:

ahlskdhfaliwh

akjsdncak

askjdbncaasb

askdjhfwi

awukldfhqwkdhad

askjiowha

jritghie

qo3r49304

efsegegsrtgsrx

sdfvn.ke


|______________

|______________|14

|__________

|__________|10

|_____________

|_____________|13

|__________

|__________|10

|________________

|________________|16

|__________

|__________|10

|_________

|_________|9

|__________

|__________|10

|_______________

|_______________|15

|_________

|_________|9

|________________________


|                    

|        _           

|       | |      _   

|_      | |     | |  

| |  _  | |     | |  

| | | | | |     | |  

| | | | | |     | |  

| |_| |_| |_   _| |  

| | | | | | |_| | |_ 

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

| | | | | | | | | | |

|_|_|_|_|_|_|_|_|_|_|____

     为了实现程序的重用性,打印输入中各个字符出现次数的直方图中依然使用上面水平方向和垂直方向的直方图绘制方式,除了对输入字符串进行元素统计那部分之外。

#include<stdio.h>

#include<string.h>

#define MAXLINE 100

//编写一个程序,打印输入中各个字符出现频度的直方图

int max(int a[MAXLINE],int item_length);

int main()

{

    int i,j,it, count,c;

    char content[MAXLINE];

    int item[MAXLINE];

    int array[MAXLINE];

    

    for(i=0;i<MAXLINE;++i)

        array[i]=1;//item初始化为1

    

    i=content[0]=0;//content初始化第一个元素

    it=count=0;

    while((c=getchar())!=EOF&&c!='\n'){

        count=0;//count重置0

        for(j=0;j<i;++j){

            if((char)c!=content[j])

               ++count;//当新的元素与原字符串当中第j个元素不相等时,count+1

            else

                ++array[j];//当新字符与原字符串当中第j个元素相等时,计数在item中第j个位置累加

         }

        if(count==i){//count与字符串个数相等时,说明新字符在原字符串当中没有,把新字符放进原字符串当中,并将字符串个数增加一位

                content[i]=(char)c;

                ++i;

        }

    }

    if(c=='\n'){

        content[i]='\n';

        ++i;

    }

        content[i]='\0';

        printf("%s",content);

    for(j=0;j<i-1;++j){

        item[j]=array[j];

        printf("%d",item[j]);

    }

    it=j;

    //水平方向

    for(i=0;i<it;++i){

        printf("\n%c",124);//先打印竖线

        for(j=0;j<item[i];++j){    //横线

            printf("%c",95);

        }

        printf("\n%c",124);

        {for(j=0;j<item[i];++j){    //横线

            printf("%c",95);

        }

            printf("%c",124);//表格前端的竖线

            printf("%d",item[i]);//表格前面的数字

        }

    }

    printf("\n%c",124);

    //为了防止横坐标小于条形长度,需要自动对横坐标长度进行计算,比如最大条形长度的1.5

    //那么需要确定数组item中最大的数组长度,可以使用数组元素依次比较的方法

    for(i=0;i<max(item, it)*1.5;++i){

        printf("%c",95);

    }

    printf("\n");

    

    //垂直方向

    for(j=0;j<max(item,it)+2;++j){

        printf("\n%c",124);//纵坐标单位长度|

        for(i=0;i<it*2;++i){

            if(i%2!=0){

                if(max(item, it)-j+1<item[i/2]||max(item, it)-j+1<item[i/2+1]){

                    printf("%c",124);// 条形图边缘的|

                }

                else{

                    printf("%c",32);

                } //条形图外部上方

            }

            else{

                if(max(item, it)+2-j-item[i/2]==1){

                    printf("%c",95);//条形图上端

                }

                else if((j!=max(item,it)+1)&&(j!=max(item,it)+2)){

                    printf("%c",32);//条形图内部和上方为空

                }

                else{

                    printf("%c",95);//条形图下端

                }

            }

        }

    }

    for(i=0;i<4;++i){

        printf("%c",95);//横坐标增加4个长度

    }

    printf("\n");

}

int max(int a[MAXLINE],int item_length)

{

    int i,max_length;

    max_length=0;

    for(i=0;i<item_length;++i){

        if (a[i]>max_length)

            max_length=a[i];

    }

    return max_length;

}

运行结果测试:

rrwkkkwwruwr4uq4qq

rwk4q

35324

|___

|___|3

|_____

|_____|5

|___

|___|3

|__

|__|2

|____

|____|4

|________


|          

|  _       

| | |    _ 

|_| |_  | |

| | | |_| |

| | | | | |

|_|_|_|_|_|____


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值