1. 字符串处理实战:数字反转问题的深度解析
这道数字反转题目看似简单,却涵盖了字符串处理的多个核心知识点。作为参加过多次算法竞赛的老手,我发现很多初学者容易在以下几个关键点翻车:字符串反转的边界控制、前导零和末尾零的处理、不同类型数字的差异化处理逻辑。下面我将结合两个版本的代码,详细拆解每个技术细节。
1.1 问题需求分析
题目要求处理四种数字格式的反转操作:
- 整数:直接反转所有数字位,需去除前导零(如"004500"反转后应为"54")
- 小数:分别反转整数部分和小数部分,需去除整数部分前导零和小数部分末尾零(如"0034.5600"反转后应为"43.065")
- 分数:分别反转分子和分母,需去除分子和分母的前导零(如"000123/004560"反转后应为"321/0654")
- 百分数:仅反转数字部分,保留百分号,需去除数字部分前导零(如"004500%"反转后应为"54%")
关键提示:题目明确要求不进行约分操作,且输入保证分母不为零,这实际上简化了我们的处理逻辑。
1.2 核心字符串函数解析
1.2.1 isdigit()函数
cpp复制isdigit(s[i]) // 判断字符是否为数字('0'-'9')
这个函数是类型判断的基础,在本题中用于识别数字字符和操作符的分界点。需要注意的是:
- 只接受单个字符作为参数
- 对于ASCII字符,等效于判断
s[i] >= '0' && s[i] <= '9' - 在第一个非数字字符处确定操作符位置
1.2.2 reverse()函数
cpp复制reverse(s.begin(), s.begin()+tem); // 反转[begin,begin+tem)区间
reverse(s.begin()+tem+1, s.end()); // 反转(tem+1,end]区间
这是本题的核心操作函数,需要特别注意:
- 参数必须是迭代器,不能直接传下标(如
s[i]是错误用法) - 区间是左闭右开的,所以第二个参数指向的是区间末尾的下一个位置
- 操作会直接修改原字符串
1.2.3 substr()函数
cpp复制s.substr(0, i); // 从位置0开始截取i个字符
s.substr(i); // 从位置i截取到字符串末尾
用于提取子字符串,在本题中主要用于:
- 分离数字部分和操作符
- 去除前导零时截取有效部分
- 处理小数和分数时分离不同部分
1.2.4 find()函数
cpp复制res.find('.'); // 返回字符'.'首次出现的位置
在反转后重新定位操作符位置时使用,需要注意:
- 返回类型是size_t(无符号整数)
- 未找到时返回
