一、题目描述
本题的任务是编写函数来判断字符是否可作为十六进制数字
// 这这这也太水了吧?十六进制数字就是[0-9A-Fa-f]
嘛。
输入规格
- 输入由多组数据构成。
- 每组数据开头有一个非负整数N表示后续数据的行数,然后换行。
- 之后有N行字符串,请整行读入,并统计字符总数、可作为十六进制数字的字符数
- N=0时表示输入结束,该组无需处理。
- 本题考察性能:总字符数可能多达几十M。
输出规格
- 对每组数据输出字符总数、可作为十六进制数字的字符数,间隔一个空格,然后换行。
样例输入
3
0123456789
ABCDEF
abcdefZ
1
:)
0
样例输出
23 22
2 0
样例解释
- 第1组有3行,共23个字符,能作为十六进制数字的有22个。
- 第2组有1行,共2个字符,能作为十六进制数字的有0个。
- 最后的0表示结束,无需处理。
参考思路()
这是个基础的工具函数,所以要尽量快。有几种实现方法:
- 条件判断组合。条件共分3段,判断逻辑的写法对性能有影响吗?
- 如果得知使用场合是处理美国人或中国人开发的代码,有何针对性的优化?
- 查表法:用字符编码作为下标访问标志数组
bool flag[256];
- 用C/C++的库函数
isxdigit(int)
,注意库函数的声明和返回类型的区别。 - 正则表达式功能强大,但对本题太慢了。
参考代码
#include <iostream>
using namespace std;
inline bool is_hex(char c){ // 被高频调用的小函数适合内联。
return false; // TODO
}
int main(){
ios::sync_with_stdio(false); // 这两行能极大加速C++的输入性能。
cin.tie(nullptr); // 代价是不能混用scanf/printf。
for(int n; cin >> n, cin.get(), n > 0;){
int t = 0, h = 0;
for(string s; n--;){
getline(cin, s);
t += s.size();
for(char c : s){
if(is_hex(c)){
++h;
}
}
}
cout << t << ' ' << h << endl;
}
}
二、完整代码实现C++
#include <iostream>
using namespace std;
inline bool is_hex(char c){ // 被高频调用的小函数适合内联。
if((c>='0'&&c<='9')||(c>='a'&&c<='f')||(c>='A'&&c<='F')){
return true;
}else{
return false; // TODO
}
}
int main(){
ios::sync_with_stdio(false); // 这两行能极大加速C++的输入性能。
cin.tie(nullptr); // 代价是不能混用scanf/printf。
for(int n; cin >> n, cin.get(), n > 0;){
int t = 0, h = 0;
for(string s; n--;){
getline(cin, s);
t += s.size();
for(char c : s){
if(is_hex(c)){
++h;
}
}
}
cout << t << ' ' << h << endl;
}
}