使用日志函数(没有 math.h)和数组计算 C 中的字母表

标签 c arrays count character logarithm

我的一个项目遇到了一个小问题。我应该编写一个 c 程序来计算输入/文件中存在的每个字符。 (它应该是一个基本程序。)约束 - 我不能使用 math.h 库来生成日志函数并获得以下格式的输出:

    1                                           
    5   1 2 0 2 2 5 8     4 3 6 6 2   5 5 7 2 1 1   2   
    7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2 
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

程序应该计算标准输入流中每个字母(不区分大小写)的出现次数并显示直方图。

如您所见,输出是垂直格式化的,每行打印字符位置的以 10 为底的数字。 现在,这可能看起来很愚蠢,但到目前为止我所拥有的是:

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

    /*
    int logBase10 (int num) {
       method to calculate the log base 10 of num
    }
    */

    int main (int argc, char * argv[]) {
        char alpha;
        int count = 0;
        int ascii[128] = {0};

        while ( (alpha = getchar()) != EOF) {
            count++;
            ascii[(int)alpha]++;
            alpha = getchar();
        }

        printf("Char \t Count \n");
        printf("------------------------\n");

        for (int i = 0; i < 127; i++) {
            if(ascii[i] > 0) {
                printf("%c \t %d \n", i, ascii[i]);
            }
        }
    }

产生这样的输出:

    Char     Count 
    ------------------------

         5 
         93 
    ,    6 
    -    2 
    .    3 
    ;    2 
    C    2 
    I    6 
    N    1 
    T    1 
    W    2 
    a    26 
    b    5 
    c    8 
    d    13 
    e    55 
    f    11 
    g    7 
    h    28 
    i    32 
    k    3 
    l    26 
    m    17 
    n    31 
    o    27 
    p    12 
    q    1 
    r    26 
    s    22 
    t    42 
    u    11 
    v    8 
    w    8 
    y    13 
    z    1 

首先,我的程序正在打印不需要的 ascii 字符(、; - 等),我正在努力将打印功能更改为更垂直,但我根本无法弄清楚日志方法。我知道 log(10) 是 1,因为 10^1 是 1,但我无法弄清楚如何使用它来创建方法本身。另外,对于额外的字符,我尝试使用:

    if(ascii[i] > 65 || ascii[i] < 90 || ascii[i] >= 97 || ascii[i] <= 122 ) {
        printf("%c \t %d \n", i, ascii[i]);
    }

没有用。尝试这样做会产生更多乱码。

感谢任何帮助/反馈。

  • 灵魂

最佳答案

评论者已经指出了您的代码存在的问题。这是一个只计算字母并打印垂直标签的版本。它不需要 <ctype.h><math.h> .

  • 每个字符都有一个字母索引,对于大写和小写字母,该索引是 0 到 25 之间的数字;如果字符不是字母,则为 -1。这将数组大小减少到 26。

  • 您可以通过复杂的计算找出每个数字,但最简单的方法是将数字打印成字符串。 snprintf为你做这件事。您可以将数字与字段宽度右对齐。典型 int 的最大值大约是20亿,有10位数字。你应该考虑到这一点,即使你必须通过整个 Moby-Dick 加上圣经才能得到那么多计数。

  • 您可以先假设宽度为十位,然后检查最大计数是否有十位,即是否为 1,000,000,000 或更高,以测试是否应该开始打印。然后在每次迭代中将该限制除以 10。

代码如下:

#include <stdio.h>

// return letter index or -1 for non-letter
int letter(int c)
{
    if ('a' <= c && c <= 'z') return c - 'a';
    if ('A' <= c && c <= 'Z') return c - 'A';
    return -1;
}

int main(int argc, char * argv[])
{
    int count[26] = {0};        // letter counts
    char label[26][12];         // buffer for printing numbers
    int limit = 1000000000;     // smallest 10-digit number
    int max = 0;
    int i, j;

    // read and count letters
    while (1) {
        int c = getchar();

        if (c == EOF) break;

        c = letter(c);
        if (c >= 0) count[c]++;
    }

    // write auxiliary labels
    for (i = 0; i < 26; i++) {
        snprintf(label[i], sizeof(label[i]), "%10d", count[i]);
        if (count[i] > max) max = count[i];
    }

    // print vertical labels
    for (j = 0; j < 10; j++) {
        if (max >= limit) {        
            for (i = 0; i < 26; i++) {
                putchar(' ');
                putchar(label[i][j]);
            }
            putchar('\n');
        }
        limit /= 10;
    }

    // print horizontal rule
    for (i = 0; i < 26; i++) {
        putchar('-');
        putchar('-');
    }
    putchar('-');
    putchar('\n');

    // print letters
    for (i = 0; i < 26; i++) {
        putchar(' ');
        putchar('A' + i);
    }
    putchar('\n');

    return 0;
}

在你的例子中,它产生:

         1                                          
 5   1 2 0 2 2 5 8     4 3 6 6 2   5 5 7 2 1 1   2  
 7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
-----------------------------------------------------
 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

关于使用日志函数(没有 math.h)和数组计算 C 中的字母表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35415730/

相关文章:

xml - 使用未知大小的数组中的项目作为选项在 powershell 中创建菜单

Django : Count, 多对多字段的分组依据和排序依据

javascript - 如何计算 Excel 表格中数据的行数

r - 转换为正确的格式并对数据框中的项目进行计数

c - 在 C 中实现有限状态机

c - MikroC:将引脚作为参数传递给函数

c - 指针和数组在内存方面的区别

Javascript 插入奇怪的换行符

C 未定义行为 - 单链表

C矩阵函数分割错误