3

所以我想做的是制作a、b、c、d等频率的直方图。我想知道为什么当我给程序一个 say 的输入时abcde,只出现一次other时会被计算多次。e

我正在寻找输入的输出abcde

 a:x
 b:x
 c:x
 d:x
 other:x

实际的K&R练习是打印输入中出现的不同字符的直方图。我的代码似乎效率极低,所以我想知道我是否在正确的方向上回答这个练习。任何指导将不胜感激。代码如下。

#include <stdio.h>

main()
{
    int i, c, na, nb, nc, nd, nother;

    na = nb = nc = nd = nother = 0;

    while( (c = getchar()) != EOF ) {
        if(c == 'a')
            na++;
        if(c == 'b')
            nb++;
        if(c == 'c')
            nc++;
        if(c == 'd')
            nd++;
        else nother++;
    }

    printf("a:");
    for(i == 0; i < na; i++) {
        putchar('x');
    }

    printf("\nb:");
    for(i = 0; i < nb; i++) {
        putchar('x');
    }

    printf("\nc:");
    for(i = 0; i < nc; i++) {
        putchar('x');
    }

    printf("\nd:");
    for(i = 0;i < nc; i++) {
        putchar('x');
    }

    printf("\nother:");
    for(i = 0;i < nother; i++){
        putchar('x');
    }
}
4

5 回答 5

5

两个问题。

第一个问题:

if(c== 'a')
    na++;
if(c== 'b')
    nb++;
if(c== 'c')
    nc++;
if(c== 'd')
    nd++;
else nother++;

这不是一个 else-if 链,因此它可以做多种不同的事情。例如:

如果字符是 a,它会命中c == 'a'if 分支和 'it's not c == 'd'' else 分支(因为 a 不等于 'd',它会前进到 else 部分并递增 nother)。

修复它如下:

if(c== 'a')
    na++;
else if(c== 'b')
    nb++;
else if(c== 'c')
    nc++;
else if(c== 'd')
    nd++;
else nother++;

第二个问题:

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

当然应该是

for(i=0;i<na;i++){
于 2013-07-12T04:27:37.853 回答
0

首先是一个小代码来找出你的系统的字符:

#include<stdio.h>

int main()
{
  int i;
  for(i=0; i < 128; ++i){
    printf("%3d ", i);
    putchar(i);
    printf("\n");
  }
  }

这将为您提供 32 到 127 的范围。然后这个工作

#include <stdio.h>

/*Write a program to print a histogram of the frequencies of different characters
in its input.*/

#define FIRST_CHAR 32 //characters start from here
#define LAST_CHAR 127 // and last till here
#define NUM_CHAR (LAST_CHAR - FIRST_CHAR) + 1 // total ~96

main()
{
  int i;
  int nchars[NUM_CHAR]; 
  for(i = 0; i < NUM_CHAR; ++i)
    nchars[i] = 0;

  int input;
  while( (input=getchar()) != EOF)
    if( (input >= FIRST_CHAR) && (input <= LAST_CHAR) ) 
      ++nchars[input- FIRST_CHAR]; //input minus first char
                                   //will give pos in index.
  int z;
  char A = ' ';                   //a char used
  for(z=0; z < NUM_CHAR; ++z){    //for
    printf("%2c", A);             //printing
    ++A;                          //list of letters

    int counter = 0;              //use a counter to keep track of how many *'s printed
    for(i=0; i < nchars[z]; i++){ 
      if(counter < 70){           //keep printing if less that 70
    printf("*");
    ++counter;}
      else{
    printf(">>>");            //else just print >>> and be done with it
    counter = 0;
    break;}                   //breaks the nearest loop or switch
      }
    printf("\n");}
}
于 2013-10-02T20:42:16.203 回答
0
#include<stdio.h>
main()
{
  int charcount[95],c,i=0,max=0;
  for(i=0;i<95;++i) /*Setting every array point to zero*/
    {
      charcount[i]=0;
    }
  while((c=getchar())!=EOF) /*Frequency of each character*/
    {    
      ++charcount[c-32];
    }
  for(i=0;i<95;++i) /*For character count of the longest word*/
    {
      if(max<charcount[i])
    max=charcount[i];
    }
  printf("\n");
  for(i=max;i>=0;--i) /*Printing the Vertical Histogram*/
    {
      for(c=0;c<95;++c)
    {
      if(charcount[c]!=0)
        {
          if((charcount[c]-i)<0)
        {
          printf("  ");
        }
          else if(i==0)printf("==");
          else printf(" X");
        }
    }
      printf("\n");
    }
  for(i=0;i<95;++i) /*Printing the Characters below the Histogram for reference*/
    {
      if(charcount[i]!=0)
    {
      if(i==0)printf("sp "); /*We would write "sp" that stands for space*/
      else printf("%c ",i+32);
    }
    }
  printf("\n");
}

垂直对齐

输出看起来像这样: “这不是斯巴达”,士兵喊道。使者走开了。:)

 X                                                
 X                                                
 X                   X                            
 X                   X                            
 X                   X                            
 X                   X                            
 X               X   X                     X      
 X               X   X         X           X      
 X               X X X   X X   X         X X X    
 X X     X     X X X X   X X   X   X X   X X X X X
 X X X X X X X X X X X X X X X X X X X X X X X X X
==================================================
sp " ) , . : S T a d e g h i k l m n o p r s t w y 
于 2013-12-25T12:04:50.033 回答
0
#include <stdio.h>
main() {
  int c, i, n, nc;                                                            
  nc = '~' - ' '; // range of ascii values to count                           
  int ndigit[nc];                                                             
  for (i = 0; i < nc; ++i)                                                    
      ndigit[i] = 0;                                                          
  while ((c = getchar()) != EOF) {                                            
      ++ndigit[c-' '];                                                        
      if (c == '\n') {                                                        
          for (i = 0; i < nc; i++)                                            
              if (ndigit[i] != 0) {                                           
                  printf("%c: ", i + ' ');                                    
                  for (n = 0; n < ndigit[i]; n++) {                           
                      printf("-");                                            
                  }                                                           
                  printf("\n");                                               
              }                                                               
          for (i = 0; i < nc; ++i)                                            
              ndigit[i] = 0;                                                  
      }                                                                       
  }
}                                                                           

样本输入:

aa bbb cccc x

输出:

 : ---
a: --
b: ---
c: ----
x: -
于 2018-06-15T10:05:06.620 回答
0

Answer Book鼓励使用标准库提供的字符分类功能,以便从控制字符和空格中识别可打印字符。 使用它们不仅可以将不同类型的字符放入定义明确的组中,而且在这个特定练习的情况下,可以用于最终报告的详细表示。 例如,在阅读循环中,函数可以将可打印字符的总数计算为

isprint

int printable = 0;
while ( (c = getchar()) != EOF )
    if ( isprint(c) )
        ++printable;

同时阻止程序员制定类似的东西

if (c >= ' ' && c <= '~')

事实上,可能性是无限的。以下是 The Answer Book 解决方案的修改版本。

#include <stdio.h>
#include <ctype.h>

#define MAXHIST 15  /* max length of histogram  */
#define MAXCHAR 128 /* max different characters */

int main()
{
    int c,
        i,
        len,         /* length of each bar      */
        maxvalue,    /* maximum value of cc[]   */
        cc[MAXCHAR], /* char frequency counters */
        totalc,      /* total chars of input    */
        whitec,      /* whitespaces chars       */
        digitc,      /* numeric chars           */
        upperc,      /* uppercase chars         */
        lowerc,      /* lowercase chars         */
        punctc;      /* punctuation marks       */

    totalc = whitec = digitc =
    upperc = lowerc = punctc = 0;

    for (int i = 0; i < MAXCHAR; ++i)
        cc[i] = 0;

    while ((c = getchar()) != EOF)
        if(c >= 0 && c < MAXCHAR) {
            ++cc[c];
            ++totalc;

            if      (isspace(c)) ++whitec;
            else if (isdigit(c)) ++digitc;
            else if (isalpha(c)) {
                if (isupper(c)) ++upperc;
                else            ++lowerc;
            }
            else if (ispunct(c)) ++punctc;
        }

    maxvalue = 0;
    for (i = 0; i < MAXCHAR; ++i)
        if (cc[i] > maxvalue)
            maxvalue = cc[i];

    printf("\n%s - %s - %s\n", "ASCII", "CH", "Freq");
    printf("~~~~~~~~~~~~~~~~~~~~\n");   
    for (i = 0; i < MAXCHAR; ++i) {
        if (cc[i] == 0)
            continue;
        if (isprint(i))
            printf("%5d - %2c - %5d : ", i, i, cc[i]);
        else
            printf("%5d -    - %5d : ", i, cc[i]);

        if (cc[i] > 0) {
            if ((len = cc[i] * MAXHIST / maxvalue) <= 0)
                len = 1;
        } else
            len = 0;

        while (len > 0) {
            putchar('*');
            --len;
        }
        putchar('\n');
    }

    printf("\n*** Detailed report ***\n");
    printf("Total # of chars      : %4d\n"
           "Total # of whitespaces: %4d\n"
           "Total # of numbers    : %4d\n"
           "Total # of letters    : %4d (%4d upper + %4d lower)\n"
           "Total # of puncts     : %4d",
           totalc, whitec, digitc, 
           upperc + lowerc, upperc, lowerc,
           punctc);
}

样本输入 (OP的第一段)

所以我想做的是制作 a、b、c、d 和其他频率的直方图。我想知道为什么当我给程序输入说“abcde”时,当“e”只出现一次时,“其他”被计算多次。

样本输出

ASCII - CH - Freq
~~~~~~~~~~~~~~~~~~~~
   32 -    -    43 : ***************
   34 -  " -     2 : *
   39 -  ' -     5 : *
   44 -  , -     4 : *
   46 -  . -     2 : *
   73 -  I -     3 : *
   97 -  a -    12 : ****
   98 -  b -     2 : *
   99 -  c -     7 : **
  100 -  d -     6 : **
  101 -  e -    18 : ******
  102 -  f -     4 : *
  103 -  g -     5 : *
  104 -  h -    10 : ***
  105 -  i -     8 : **
  107 -  k -     1 : *
  108 -  l -     1 : *
  109 -  m -     6 : **
  110 -  n -    14 : ****
  111 -  o -    18 : ******
  112 -  p -     2 : *
  113 -  q -     1 : *
  114 -  r -    10 : ***
  115 -  s -     8 : **
  116 -  t -    13 : ****
  117 -  u -     4 : *
  118 -  v -     1 : *
  119 -  w -     6 : **
  121 -  y -     5 : *

*** Detailed report ***
Total # of chars      :  221
Total # of whitespaces:   43
Total # of numbers    :    0
Total # of letters    :  165 (   3 upper +  162 lower)
Total # of puncts     :   13 
于 2018-09-13T17:00:31.340 回答