#include <algorithm> 换一种,没有学过
时间: 2025-07-21 07:50:39 浏览: 1
<think>我们避免使用<algorithm>中的reverse函数,可以手动反转字符串。
修改思路:自己写一个循环来反转字符串,或者直接使用双指针比较(这样就不需要反转整个字符串了)。
为了简单易懂,我们使用双指针方法,这样就不需要反转字符串了。
具体步骤:
1. 将数字转换为字符串s。
2. 使用两个指针,一个从头部开始,一个从尾部开始,向中间移动。
3. 比较两个指针指向的字符是否相同,如果不同则不是回文。
4. 同时,在比较过程中检查是否有字符'7'(可以设置一个标志变量)。
但是注意:在双指针比较时,我们可以同时完成回文检查和是否有7的检查。
然而,为了简单,我们可以分开做:
先检查是否是回文,再检查是否包含7。但这样需要遍历两次字符串。
为了效率,我们可以在同一个循环中完成。
但题目要求简单易懂,我们可以先做回文检查,再做包含7的检查,这样逻辑更清晰。
修改后的代码:
步骤:
for (int num = a; num <= b; num++) {
string s = to_string(num);
// 检查回文
bool isPalindrome = true;
for (int i = 0; i < s.size()/2; i++) {
if (s[i] != s[s.size()-1-i]) {
isPalindrome = false;
break;
}
}
// 检查是否包含7
bool hasSeven = false;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '7') {
hasSeven = true;
break;
}
}
if (isPalindrome && hasSeven) {
count++;
}
}
但是这样需要两次循环,我们可以合并到一个循环吗?当然可以,但分开更清晰。
不过,我们也可以在一个循环里同时做两件事:
bool isPalindrome = true;
bool hasSeven = false;
int n = s.size();
for (int i = 0; i <= n/2; i++) { // 注意这里i<=n/2,因为对于奇数个,中间位置也要检查是否有7
// 检查对称位置
if (s[i] != s[n-1-i]) {
isPalindrome = false;
}
// 检查当前字符和对称位置的字符是否为7
if (s[i]=='7' || s[n-1-i]=='7') {
hasSeven = true;
}
// 如果已经发现不是回文,并且已经找到了7,其实可以继续,但为了效率,可以提前退出?
// 注意:即使不是回文,我们也要检查整个字符串是否有7吗?不,因为如果不是回文,我们就不需要这个数了,但是这里我们同时在做两个检查,所以不能提前退出循环,因为要检查整个字符串是否有7?不对,我们只检查了前半部分和对称的后半部分,但中间位置可能漏掉?不会,因为我们遍历了前半部分和后半部分,但中间位置(奇数个时)在i等于中间位置时,左右指针都指向同一个位置,所以不会漏。
// 但是,如果我们在循环中已经发现不是回文,并且已经找到了7,我们还需要继续检查吗?
// 我们可以提前退出:如果已经确定不是回文并且已经找到了7,那么后续的检查对结果没有影响,但是注意:即使不是回文,我们也要检查整个字符串是否有7吗?不,因为不是回文我们就不会计数,所以一旦发现不是回文,我们可以立即跳出循环,避免后续不必要的检查。但是这里我们同时在做两个检查,而且我们还需要继续检查是否有7吗?不需要,因为不是回文就直接丢弃了,所以一旦发现不对称,我们可以设置isPalindrome=false,但此时还不能跳出循环,因为可能还没有检查完整个字符串的前半部分是否有7?不对,我们只检查了对称位置,但还没有检查整个字符串是否包含7。所以这里不能提前跳出循环,因为我们需要检查整个字符串中是否有7?不对,我们并没有检查整个字符串,我们只检查了对称位置(即前半部分和后半部分),但这样已经足够,因为只要有一个位置是7,我们就标记hasSeven=true。
// 实际上,我们通过对称位置检查,已经覆盖了整个字符串:因为每个位置都被检查了(前半部分和后半部分各检查一次,中间位置一次)。所以我们可以这样:在循环中,如果发现不对称,就标记isPalindrome=false(但不跳出,因为还要检查7?),但我们可以继续,直到循环结束。或者,我们可以提前跳出回文检查,但7的检查必须继续?不,实际上我们可以在发现不对称后继续检查7,但这样没有意义,因为已经确定不是回文了,所以即使有7我们也不计数。所以我们可以提前结束循环吗?注意,即使不是回文,我们也要检查整个字符串是否有7吗?不需要,因为不是回文就直接跳过。所以一旦发现不对称,我们就可以跳出循环,但是这样我们就可能漏掉7的检查(因为只检查了前面部分)。所以我们需要在跳出循环前确保已经检查过的位置中是否有7?但是跳出循环后,我们还没有检查后半部分未检查的位置是否有7。
// 因此,为了确保正确性,我们需要遍历整个字符串来检查7?不,我们可以换一种思路:如果不是回文,我们就不关心7了,所以我们可以跳出循环,但这样我们就无法知道这个数是否包含7(因为可能后面的位置有7,但我们已经跳出,而实际上我们不需要知道,因为不是回文就不计数)。所以我们可以这样:先检查回文,在检查回文的过程中,同时记录是否遇到7(这样我们只检查了对称位置,但整个字符串的每个位置都被覆盖了,因为对称位置覆盖了所有位置)。所以,在循环中,我们同时检查对称位置的两个字符,只要有一个是7,就标记hasSeven=true。这样,即使提前跳出(因为不对称),但已经检查过的位置中如果出现了7,那么hasSeven已经被标记。但是,如果7出现在后半部分还没有检查的位置,那么当我们因为不对称而提前跳出时,那个7还没有被检查到。所以,我们不能提前跳出,必须完成整个循环?或者,我们可以不提前跳出,而是继续完成循环,这样整个字符串都被检查了(但回文检查只需要前半部分,而7的检查需要整个字符串?)。实际上,我们通过对称位置检查,已经覆盖了整个字符串:因为每次检查两个位置(除了中间位置),所以整个字符串都被检查了。因此,在循环中,我们可以同时完成两个任务。
// 但是,如果我们已经发现不对称,那么整个字符串的7检查还需要继续吗?实际上,我们可以在循环中继续,因为循环会继续检查剩下的对称位置,这样整个字符串的7都会被检查到(因为每个位置都会被访问一次)。所以,即使不对称,我们也要继续循环,直到完成整个前半部分(包括中间位置)的检查,这样就能确保整个字符串的7都被检查到。
// 然而,如果我们已经知道不对称,那么后续的对称位置比较就没有必要了,但是7的检查还是必要的,因为整个字符串中可能还有7。所以,我们可以这样:在循环中,无论是否对称,都检查两个位置的字符是否为7。这样,即使不对称,我们也要继续循环以检查7。
// 但是,这样效率可能不高,因为已经知道不是回文了,但我们还是需要遍历整个字符串的前半部分(以及对称的后半部分)来检查7。但注意,我们只需要遍历一半,因为对称位置已经覆盖了整个字符串。所以循环次数是n/2,已经比整个字符串遍历少了一半。
// 因此,我们可以在循环中同时做两件事,并且不提前退出循环(即使发现了不对称),这样保证7的检查完整。
}
但是,这样循环次数并没有减少(仍然是n/2),所以可以接受。
然而,另一种更简单的方法:先检查回文,如果不是回文就跳过,不检查7。但这样需要先遍历一半来检查回文,然后再遍历整个字符串检查7。而合并在一起,我们只需要遍历一半(但每个位置检查两次?实际上,我们通过对称位置,一次循环检查两个位置)。所以合并循环效率更高。
但是,为了简单易懂,我们分开做,因为题目要求简单。
考虑到题目要求简单,我们分开两个循环,这样逻辑清晰。
但是,题目要求没有学过<algorithm>,所以我们避免使用reverse,自己写回文检查(用双指针循环)。
我们选择分开两个循环,先检查回文,再检查7。
代码:
注意:在检查7的时候,我们可以在整个字符串中查找,但也可以提前退出(找到一个7就退出)。
所以,代码修改如下(不使用<algorithm>):</think>以下是一个不使用`<algorithm>`头文件的简单C++实现,通过手动比较字符来判断回文和数字7:
```cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
int a, b, count = 0;
cin >> a >> b;
for (int num = a; num <= b; num++) {
// 将数字转为字符串
string s = to_string(num);
int len = s.length();
bool is_palindrome = true;
bool has_seven = false;
// 手动检查回文和数字7
for (int i = 0; i < len; i++) {
// 检查回文:比较对称位置的字符
if (s[i] != s[len - 1 - i]) {
is_palindrome = false;
}
// 检查数字7
if (s[i] == '7') {
has_seven = true;
}
}
// 如果是回文且包含7,计数增加
if (is_palindrome && has_seven) {
count++;
}
}
cout << count << endl;
return 0;
}
```
**代码说明:**
1. **去掉了`<algorithm>`依赖**:不使用`reverse`函数,改为手动比较字符
2. **单次遍历完成检测**:在一个循环中同时完成回文检查和数字7检测
3. **回文检查**:通过比较字符串首尾对称位置的字符(`s[i]`和`s[len-1-i]`)
4. **数字7检测**:遍历过程中遇到'7'字符即标记为true
5. **条件判断**:同时满足回文和包含7时计数器增加
**样例验证:**
输入`6 80`时:
- 数字`7`:字符串"7"满足回文且包含7 → 计数+1
- 数字`77`:字符串"77"满足回文且包含7 → 计数+1
最终输出`2`
阅读全文
相关推荐



















