当前位置: 首页 > news >正文

PTA L1-039 古风排版:用C语言二维数组模拟竖排文字,保姆级图解教程

PTA L1-039 古风排版:二维数组与文字竖排的艺术

第一次看到古风排版题目时,我盯着那个"asa T st ih e tsi ce s"的输出样例发了十分钟呆。作为习惯了从左到右阅读的现代人,要理解这种从右向左、从上到下的文字排列方式,确实需要一些思维转换。不过当我用二维数组模拟出整个过程后,一切都变得清晰起来。

1. 理解古风排版的本质

古风排版的核心在于文字排列方向的改变。现代排版是水平方向优先,而古代排版则是垂直方向优先。这种差异直接影响了我们处理字符串的方式。

关键特征:

  • 文字从右向左排列(列顺序)
  • 每列的文字从上向下排列(行顺序)
  • 最后一列可能不足N个字符时需要补空格

举个例子,对于输入"Hello World"(N=3),应该这样思考:

H e l l o W o r l d

我们需要把这个字符串按3行分割后,从右向左排列:

原字符串分段: Hel lo Wor ld 竖排后: l oW lo H d

2. 二维数组的结构设计

用二维数组模拟这种排版,关键在于确定数组的行列关系。这里有一个思维转换:

  • 数组的行数= 用户输入的N(每列字符数)
  • 数组的列数= ceil(字符串长度 / N)
int len = strlen(input_str); int cols = len / rows; if (len % rows != 0) { cols++; // 不能整除时需要额外一列 }

这个计算确保了即使字符串长度不是N的整数倍,我们也有足够的空间存储所有字符(最后一列不足的部分用空格填充)。

3. 填充算法的逆向思维

最让初学者困惑的是填充顺序——为什么要从最后一列开始?让我们用ASCII图示来说明:

假设输入是"This is a test case",N=4:

原始字符串索引: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 T h i s i s a t e s t c a s e

我们需要创建一个4行x5列的数组(因为18个字符/4行=4.5→5列),填充顺序如下:

列号: 4 3 2 1 0 --------------------- 行0 | a | s | a | | T | 行1 | s | t | | i | h | 行2 | e | | t | s | i | 行3 | | c | s | | e |

对应的填充代码:

char grid[100][100] = {0}; int index = 0; for (int col = cols - 1; col >= 0; col--) { for (int row = 0; row < rows; row++) { if (input_str[index] != '\0') { grid[row][col] = input_str[index++]; } else { grid[row][col] = ' '; // 不足部分补空格 } } }

4. 调试技巧与常见陷阱

在实现这个算法时,我踩过几个典型的坑:

  1. 数组越界:没有正确计算列数导致访问非法内存

    • 解决方法:打印中间计算结果验证
    printf("字符串长度=%d, 需要列数=%d\n", len, cols);
  2. 空格处理:忘记处理最后一列不足时的空格补全

    • 关键检查:
    if (input_str[index] != '\0') { // 正常赋值 } else { // 补空格 }
  3. 填充顺序混淆:误从左到右填充导致顺序错误

    • 记忆技巧:想象真的在竹简上写字,从最右侧开始

调试时可以打印中间状态:

// 在填充循环内加入调试输出 printf("填充 col=%d, row=%d, char=%c\n", col, row, grid[row][col]);

5. 完整代码实现与优化

结合上述分析,这是经过优化的完整实现:

#include <stdio.h> #include <string.h> #define MAX_STR 1001 #define MAX_GRID 100 int main() { int rows; scanf("%d ", &rows); // 注意空格吸收换行 char input_str[MAX_STR]; fgets(input_str, MAX_STR, stdin); input_str[strcspn(input_str, "\n")] = '\0'; // 去除换行符 int len = strlen(input_str); int cols = len / rows; if (len % rows != 0) cols++; char grid[MAX_GRID][MAX_GRID] = {0}; int index = 0; // 从右向左填充列 for (int col = cols - 1; col >= 0; col--) { for (int row = 0; row < rows; row++) { grid[row][col] = (index < len) ? input_str[index++] : ' '; } } // 输出结果 for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { putchar(grid[row][col]); } putchar('\n'); } return 0; }

优化点:

  1. 使用fgets替代不安全的gets
  2. 用三元运算符简化条件判断
  3. 添加了数组大小宏定义,提高可维护性
  4. 更安全的换行符处理

6. 可视化理解工具

为了更直观地理解这个过程,我设计了一个简单的文本可视化方法:

void visualize_filling(int rows, int cols, const char grid[][MAX_GRID]) { printf("\n填充过程可视化:\n"); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%2d:%-2c ", i * cols + j, grid[i][j]); } printf("\n"); } }

调用这个函数可以看到字符是如何被填入二维数组的,对于调试特别有帮助。

7. 性能分析与扩展思考

虽然这个问题规模很小(N<100,字符串<1000),但思考优化方案是很好的练习:

  1. 空间优化:可以直接计算输出位置,不需要二维数组
    • 公式:输出字符位置 = (cols - 1 - col) * rows + row
  2. 边界情况
    • 空字符串输入
    • N=1的情况(变成简单的字符串反转)
    • N大于字符串长度的情况

尝试实现这些优化是理解算法本质的好方法。比如无二维数组版本:

for (int row = 0; row < rows; row++) { for (int col = cols - 1; col >= 0; col--) { int index = col * rows + row; putchar(index < len ? input_str[index] : ' '); } putchar('\n'); }

这种实现直接计算字符位置,节省了O(N²)的空间,但可读性稍差。在算法竞赛中,这种优化往往很有价值。

http://www.jsqmd.com/news/779178/

相关文章:

  • 2026高档旅行箱实测|5款国标认证款,静音耐造适配商务家庭全场景 - GrowthUME
  • uni-app怎么做类似于淘宝的物流单号自动识别 uni-app正则匹配逻辑实现【实战】.txt
  • 基于MCP协议构建AI智能体环境数据工具集:以wet-mcp为例
  • 2026年罗氏虾工厂对比:如何选择技术强、供应稳的养殖场? - GrowthUME
  • ResearchClawBench:评估AI独立科研能力的硬核基准与实战指南
  • ARM流水线架构与指令执行优化实战
  • 2025届学术党必备的十大AI科研神器横评
  • 程序员的中年危机不是年龄,而是“技能负债”
  • c -> true 导致异常返回 404 问题排查
  • 别再只会用积分球测光通量了!手把手教你用便携式LS-ISLS20K校准你的工业相机
  • 【留子必看】2026英文降AI率实操:3招告别Turnitin标蓝,AI率80%降至10% - 殷念写论文
  • 天津救助站哪个靠谱 - GrowthUME
  • AI驱动的联盟营销自动化:从数据决策到闭环增长实战
  • 朱伟领社员进社区,暖阿尔茨海默病患者心 - 博客湾
  • Qt QTreeView实战:用QStandardItemModel构建一个简易文件管理器(附完整源码)
  • LED照明电源设计革新:从降压到升压架构的效率与热管理优化
  • SQL Server如何实现编写表与字段注释_Navicat兼容操作步骤
  • 告别理论!手把手用Verilog/SystemVerilog搭建一个简易的PCIe初始化验证环境
  • 2026品牌定制5大AI数字人直播平台盘点:支持专属虚拟形象搭建
  • 山东商用展示柜厂家|冰怪兽全系网红展示柜定制与批发 - GrowthUME
  • 2025届最火的六大AI论文方案解析与推荐
  • Godot引擎AI智能体集成:MCP协议实现自然语言驱动游戏开发
  • 前端框架演进史:从 jQuery 到 Vue,一场持续十五年的变革
  • Unity AI助手工具链:基于MCP协议实现项目感知与编辑器操作
  • 从IDF 2012看英特尔技术十字路口:Haswell能效革命与Atom移动困局
  • Go语言现代化CLI工具开发:从clawon框架看命令行应用构建
  • kode:harness:统一团队AI编码方向的工程框架
  • 发票识别OCR API接入详解:自动提取发票全字段并接入财务系统(附Python/JS/PHP示例)
  • 下一代物联网基站硬件设计:从异构计算到信号完整性的工程实践
  • 如何进阶使用 Claude Code