1. 东华OJ基础10-12题解析
作为一名计算机专业的学生,刷题是提升编程能力的必经之路。东华OJ平台的基础10-12题是面向初学者的经典练习题,涵盖了基本的编程思维和语法运用。这三道题目虽然看似简单,但其中蕴含着许多值得深入探讨的编程技巧和思考方式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目分析与解题思路
2.1 基础10题:数字反转
这道题要求将一个整数反转输出。看似简单的需求,实际上需要考虑多种边界情况:
- 正负数的处理
- 末尾有0的情况
- 反转后可能出现的溢出问题
c复制#include <stdio.h>
#include <limits.h>
int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > INT_MAX/10 || (rev == INT_MAX/10 && pop > 7)) return 0;
if (rev < INT_MIN/10 || (rev == INT_MIN/10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
注意:在处理整数反转时,必须考虑32位整数的范围限制。INT_MAX和INT_MIN是标准库中定义的常量,分别表示int类型的最大值和最小值。
2.2 基础11题:字符串统计
这道题要求统计字符串中各类字符的出现次数。主要考察点包括:
- 字符串的遍历方法
- 字符分类判断
- 计数器的使用
c复制#include <stdio.h>
#include <ctype.h>
void countChars(char *str) {
int letters = 0, digits = 0, others = 0;
while (*str) {
if (isalpha(*str)) letters++;
else if (isdigit(*str)) digits++;
else others++;
str++;
}
printf("Letters: %d\nDigits: %d\nOthers: %d\n", letters, digits, others);
}
提示:使用ctype.h中的isalpha()和isdigit()函数可以简化字符类型的判断,比直接比较ASCII码更可靠。
2.3 基础12题:矩阵转置
矩阵转置是线性代数中的基础操作,这道题考察二维数组的处理能力:
- 二维数组的定义和初始化
- 行列交换的实现
- 输出格式的控制
c复制#include <stdio.h>
#define N 3
void transpose(int mat[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = i; j < N; j++) {
int temp = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = temp;
}
}
}
3. 常见问题与解决方案
3.1 数字反转中的溢出问题
很多同学在解决数字反转问题时,常常忽略整数溢出的情况。当反转后的数字超过int类型的表示范围时,程序会出现未定义行为。解决方案有两种:
- 使用更大范围的整数类型(如long long)
- 在反转过程中实时检查是否可能溢出
c复制// 溢出检查的另一种实现
if (rev > INT_MAX/10 || rev < INT_MIN/10) {
return 0; // 溢出
}
3.2 字符串统计中的边界情况
在处理字符串统计时,需要注意以下特殊情况:
- 空字符串的处理
- 包含空格、制表符等空白字符的情况
- 非ASCII字符的处理
3.3 矩阵转置的效率优化
对于N×N的方阵,转置操作可以优化为只遍历矩阵的上三角或下三角:
c复制for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
// 交换元素
}
}
这种优化可以将时间复杂度从O(N²)降低到O(N²/2),虽然渐进复杂度相同,但实际运行时间会有所改善。
4. 编程技巧与最佳实践
4.1 代码风格建议
- 使用有意义的变量名:避免使用单个字母作为变量名(除非是循环计数器)
- 添加适当的注释:解释复杂的逻辑或算法
- 保持一致的缩进风格:建议使用4个空格缩进
4.2 调试技巧
- 使用printf调试:在关键位置打印变量值
- 分步验证:先实现核心功能,再处理边界情况
- 单元测试:为每个函数编写测试用例
4.3 性能考量
虽然这些基础题目对性能要求不高,但养成良好的性能意识很重要:
- 避免不必要的计算
- 减少内存访问次数
- 选择合适的数据结构
5. 扩展练习建议
掌握了这三道基础题后,可以尝试以下扩展练习:
- 实现任意长度整数的反转(使用字符串处理)
- 统计文件中各类字符的出现次数
- 实现非方阵的转置操作
- 将这些功能封装成独立的函数库
c复制// 扩展:任意长度整数反转(字符串实现)
void reverseStringNumber(char *num) {
int len = strlen(num);
int i = 0, j = len - 1;
if (num[0] == '-') i = 1; // 跳过负号
while (i < j) {
char temp = num[i];
num[i] = num[j];
num[j] = temp;
i++;
j--;
}
// 去除前导零
int start = (num[0] == '-') ? 1 : 0;
while (num[start] == '0' && start < len - 1) start++;
if (start > 0) {
memmove(num + ((num[0] == '-') ? 1 : 0), num + start, len - start + 1);
}
}
6. 学习资源推荐
- 《C Primer Plus》:全面系统的C语言教程
- LeetCode平台:更多算法练习题
- GeeksforGeeks网站:丰富的编程教程和示例
- 东华OJ的其他题目:逐步提升编程能力
在实际编程练习中,我建议先从理解题目要求开始,然后设计测试用例,最后再着手编写代码。这种"先思考后编码"的习惯能显著提高编程效率和质量。对于初学者来说,遇到问题时不要急于查找答案,先尝试自己调试和解决,这样获得的经验更为宝贵。
