文章目录
- 💯前言
- 💯题目描述与输入输出要求
- 题目:统计数字字符个数
- 样例输入输出
- 💯方法分析与代码实现
- 方法 1:使用 `fgets` 读取输入并手动判断数字字符
- 代码实现
- 分析与优点
- 缺点与优化方向
- 方法 2:使用 `scanf` 格式化输入并手动判断数字字符
- 代码实现
- 分析与优点
- 缺点与优化方向
- 方法 3:引入 `isdigit` 函数简化判断逻辑
- 代码实现
- 分析与优点
- 实现与优化建议
- 改进版 1:去除换行符并使用现代 C++
- 分析与优点
- 💯拓展讨论
- 💯总结
💯前言
- 在学习编程的过程中,常常会遇到诸如"统计数字字符个数"这样的问题。看似简单,但通过不同方法实现,可以让我们深入理解输入输出的处理、字符判断的技巧以及代码优化的可能性。在本文中,我们围绕一个具体的题目展开,从题目分析开始,依次解读老师的几种实现方法以及我的实践方法,进行详细的思路对比,并提出进一步优化方案及拓展讨论。
通过这篇文章,读者将不仅学会如何解决数字字符统计问题,还能理解背后的代码设计和优化思路,从而提高自身编程能力。
C++ 参考手册
💯题目描述与输入输出要求
B2109 统计数字字符个数
题目要求如下:
题目:统计数字字符个数
- 描述:输入一行字符串,统计出其中数字字符的个数。
- 输入格式:
- 一行字符串,总长度不超过 255。
- 输出格式:
- 输出为 1 行,表示字符串中数字字符的个数。
样例输入输出
输入样例 #1:
Today is 2021-03-27
输出样例 #1:
8
输入样例 #2:
hello123world456
输出样例 #2:
6
💯方法分析与代码实现
方法 1:使用 fgets
读取输入并手动判断数字字符
代码实现
#include <iostream>
#include <cstring>
using namespace std;
const int N = 266;
char arr[N];
int main()
{
// 使用 fgets 读取带空格的字符串,并自动在末尾加上字符串结束符 \0
fgets(arr, N, stdin);
int i = 0;
int c = 0;
// 遍历字符串,直到遇到换行符 '\n'
while (arr[i] != '\n')
{
if (arr[i] >= '0' && arr[i] <= '9') // 判断是否是数字字符
c++; // 数字字符计数
i++;
}
cout << c << endl;
return 0;
}
分析与优点
-
输入方式:
- 使用
fgets
安全读取整行字符串,可以处理带有空格的输入。 - 自动在字符串末尾加上结束符
\0
,无需手动添加。
- 使用
-
逻辑清晰:
- 使用
while
遍历字符数组,条件判断为arr[i] != '\n'
,明确以换行符为终止标志。 - 手动通过
if
判断字符是否在'0'
到'9'
范围内,简单直接。
- 使用
-
适用场景:
- 适用于需要逐字符处理的简单任务。
缺点与优化方向
-
多余的换行符处理:
- 使用
fgets
会将换行符也作为输入的一部分,需手动判断并跳过。 - 可在读取完成后用以下方式去除换行符:
int len = strlen(arr); if (arr[len - 1] == '\n') arr[len - 1] = '\0';
- 使用
-
代码略显繁琐:
- 手动比较字符 ASCII 值,虽然简单,但冗长且容易出错。
方法 2:使用 scanf
格式化输入并手动判断数字字符
代码实现
#include <iostream>
#include <cstring>
using namespace std;
const int N = 266;
char arr[N];
int main()
{
// 使用 scanf 读取一行输入,遇到换行符 \n 停止,不会将 \n 存入 arr
scanf("%[^\n]", arr);
int i = 0;
int c = 0;
// 遍历字符串,直到遇到字符串结束符 '\0'
while (arr[i] != '\0')
{
if (arr[i] >= '0' && arr[i] <= '9')
c++;
i++;
}
cout << c << endl;
return 0;
}
分析与优点
-
输入方式更简洁:
- 使用
scanf
和格式控制符%[^ ]
,读取整行字符串,遇到换行符停止,避免了换行符的干扰。
- 使用
-
逻辑清晰:
- 遍历条件为
arr[i] != '\0'
,标准的 C 风格字符串操作。
- 遍历条件为
-
适用场景:
- 更适合只需要简单输入处理的场景。
缺点与优化方向
- 潜在的数组越界问题:
- 如果输入字符串长度超过 266 字符,会导致数组越界。
- 优化:为输入限制最大长度,例如:
scanf("%265[^
]", arr);
```
- 仍需手动比较字符范围:
- 判断逻辑仍然是
arr[i] >= '0' && arr[i] <= '9'
,可读性不够高。
- 判断逻辑仍然是
方法 3:引入 isdigit
函数简化判断逻辑
代码实现
#include <iostream>
#include <cctype> // 引入 cctype 以使用 isdigit 函数
using namespace std;
const int N = 266;
char arr[N];
int main()
{
scanf("%[^
]", arr);
int i = 0;
int c = 0;
while (arr[i] != '\0')
{
if (isdigit(arr[i])) // 使用 isdigit 判断是否是数字字符
c++;
i++;
}
cout << c << endl;
return 0;
}
分析与优点
-
逻辑更简洁:
- 使用
isdigit
函数代替手动比较字符范围,提升代码可读性,减少出错可能性。 isdigit
是标准库函数,专门用于判断字符是否为数字字符。
- 使用
-
适用性强:
- 适用于各种字符判断任务,扩展性更好。
-
代码优化方向:
- 保持输入安全性,限制输入最大长度:
scanf("%265[^
- 保持输入安全性,限制输入最大长度:
]", arr);
```
实现与优化建议
改进版 1:去除换行符并使用现代 C++
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string input;
getline(cin, input); // 使用 getline 读取整行输入
int count = 0;
for (char ch : input)
{
if (isdigit(ch))
count++;
}
cout << count << endl;
return 0;
}
分析与优点
-
使用
getline
替代字符数组:- 避免了数组越界问题,更加安全。
-
更现代化的风格:
- 使用 C++ 的字符串类
std::string
,更符合现代 C++ 编程习惯。
- 使用 C++ 的字符串类
-
代码简洁易读:
- 利用范围循环和
isdigit
,避免手动索引操作。
- 利用范围循环和
💯拓展讨论
-
如何统计其他字符类型?
- 可以扩展判断逻辑,使用
isalpha
判断字母字符,isspace
判断空白字符等。
- 可以扩展判断逻辑,使用
-
性能优化:
- 对于较大的输入,可考虑分块处理,减少内存占用。
-
输入校验:
- 如果输入格式不确定,应添加输入校验逻辑,确保输入合法性。
💯总结
通过本文的分析,我们从多种方法解决了"统计数字字符个数"的问题。每种方法都有其适用场景与优缺点,其中使用 isdigit
和现代 C++ 的实现更具优势。在实际开发中,选择适合问题需求的方法并进行优化,能更高效地解决问题,同时提升代码的可读性与维护性。
希望本文能帮助读者深入理解字符处理的思路与技巧,进一步提升编程能力!