You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言垂直直方图实现:星号排版间距异常问题求助

核心问题分析

你的代码存在三个关键问题,直接导致垂直直方图排版错误:

  • 数组越界访问
  • 单词计数逻辑的条件判断错误(误用赋值运算符而非比较运算符)
  • 垂直直方图的打印逻辑完全偏离需求

具体调试建议

1. 修复数组越界问题

C语言数组是0索引起始,你定义的worldlengths[MAXWORDLENGTH](MAXWORDLENGTH=10)仅能访问索引0~9,但你循环时用了i=1到10,这会访问数组外的内存,触发未定义行为。

修正方案:将数组定义为int worldlengths[MAXWORDLENGTH + 1];,这样索引110都合法,和你统计的单词长度(110)直接对应。

2. 修复单词计数的条件判断错误

代码中else if (state = OUT)是赋值操作(把OUT赋值给state),不是比较操作,这会导致每次进入该分支都会强制将state设为OUT,进而错误触发单词计数逻辑。

修正方案:把=改成比较运算符==,即else if (state == OUT)。

3. 重构垂直直方图的打印逻辑

你当前的打印循环逻辑完全错误,垂直直方图需要按行打印:

  • 先找到所有单词长度计数的最大值(确定直方图的最高行数)
  • 从最高行到第1行,逐行遍历每个单词长度列:
    • 如果该列的计数 ≥ 当前行高度,打印* (带空格的格式化星号)
    • 否则打印 (占位空格)
  • 每行打印完后换行,最后再打印横坐标(单词长度)和对应计数。

修正后的完整代码

#include <stdio.h>

#define IN 1            /* In a word */
#define OUT 0           /* Out of word */
#define MAXWORDLENGTH 10    /* Maximum word length */

int main() { // 标准C要求main返回int类型
    int c = 0, i = 0, j = 0, state = OUT, letters = 0;
    int max_count = 0;       // 记录直方图的最大高度
    int ovflow = 0;          // 统计长度超标的单词数量
    int worldlengths[MAXWORDLENGTH + 1]; // 修正数组长度,支持1~10索引

    // 初始化数组所有元素为0
    for (i = 0; i <= MAXWORDLENGTH; i++) {
        worldlengths[i] = 0;
    }

    // 统计单词长度
    while ((c = getchar()) != EOF && c != 'q') { // 合并退出条件,逻辑更简洁
        if (c == ' ' || c == '\t' || c == '\n') {
            state = OUT;
            if (letters > 0) {
                if (letters <= MAXWORDLENGTH) {
                    worldlengths[letters]++;
                    // 更新最大计数,用于确定直方图高度
                    if (worldlengths[letters] > max_count) {
                        max_count = worldlengths[letters];
                    }
                } else {
                    ovflow++;
                }
                letters = 0;
            }
        } else if (state == OUT) { // 修正为比较运算符
            state = IN;
            letters = 1; // 单词开始,计数初始化为1
        } else {
            letters++; // 单词中,计数递增
        }
    }

    // 处理循环结束时未统计的最后一个单词
    if (letters > 0) {
        if (letters <= MAXWORDLENGTH) {
            worldlengths[letters]++;
            if (worldlengths[letters] > max_count) {
                max_count = worldlengths[letters];
            }
        } else {
            ovflow++;
        }
    }

    // 打印垂直直方图
    for (i = max_count; i >= 1; i--) {
        for (j = 1; j <= MAXWORDLENGTH; j++) {
            if (worldlengths[j] >= i) {
                printf("*  ");
            } else {
                printf("   ");
            }
        }
        putchar('\n');
    }

    // 打印横坐标(单词长度)
    for (i = 1; i <= MAXWORDLENGTH; i++) {
        printf("%2d ", i);
    }
    putchar('\n');

    // 打印每个长度对应的单词数量
    for (i = 1; i <= MAXWORDLENGTH; i++) {
        printf("%2d ", worldlengths[i]);
    }
    putchar('\n');

    // 打印超长单词统计结果
    if (ovflow > 0) {
        printf("\n有 %d 个单词长度超过%d\n", ovflow, MAXWORDLENGTH);
    }

    return 0; // 标准C要求main返回值
}

额外优化说明

  • 补充了标准C要求的main函数返回值定义和返回语句
  • 合并了退出条件(EOF和输入'q'),逻辑更简洁
  • 增加了循环结束时未统计单词的处理,避免最后一个单词丢失计数
  • 新增了超长单词的统计输出,完善功能

内容的提问来源于stack exchange,提问作者user23465972

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 18:16:04