(C++)判断一个数是否是回文数(C++教程)(C++string类型教程:重点)

方法一:整数反转法(推荐)

代码逐行解析

bool isPalindrome(int num) {
    // 处理特殊情况:负数不是回文数
    if (num < 0) return false;
    
    // 个位数都是回文数(0-9)
    if (num < 10) return true;
    
    // 使用long类型防止反转后溢出
    long reversed = 0;
    // 保存原始值用于比较
    int original = num;
    
    // 反转整数算法
    while (num > 0) {
        // 取出最后一位数字并添加到反转数中
        reversed = reversed * 10 + num % 10;
        // 去掉最后一位数字
        num /= 10;
    }
    
    // 比较原始数和反转数
    return original == reversed;
}

详细解释(新手友好)

  1. 处理特殊情况

    • if (num < 0) return false;:负数不可能是回文数,比如 -121 反转后是 121-,不相等

    • if (num < 10) return true;:0-9 都是回文数,因为单个数字正反都一样

  2. 防止溢出

    • long reversed = 0;:使用 long 类型(4字节或8字节)而不是 int,避免反转大数时溢出

    • 例如:输入 2147483647(int最大值),反转后为 7463847412,超出 int 范围

  3. 反转算法核心

    • reversed = reversed * 10 + num % 10;

      • num % 10:获取数字的最后一位

      • reversed * 10:将已有数字左移一位(十进制)

      • 例如:处理 123:

        • 第一次:reversed = 0*10 + 3 = 3

        • 第二次:reversed = 3*10 + 2 = 32

        • 第三次:reversed = 32*10 + 1 = 321

    • num /= 10;:去掉最后一位

      • 例如:123 / 10 = 12

  4. 比较结果

    • return original == reversed;:检查反转后是否与原始数相等

使用示例

#include <iostream>
using namespace std;

int main() {
    int num;
    cout << "请输入一个整数: ";
    cin >> num;
    
    if (isPalindrome(num)) {
        cout << num << " 是回文数" << endl;
    } else {
        cout << num << " 不是回文数" << endl;
    }
    
    return 0;
}

扩展知识:整数反转技巧

整数反转是编程中常见的技术,除了回文数判断,还可以用于:

  1. 数字逆序输出

    void reversePrint(int n) {
        while (n) {
            cout << n % 10;  // 输出最后一位
            n /= 10;
        }
    }
  2. 整数反转函数

    int reverseNumber(int n) {
        long reversed = 0;
        while (n) {
            reversed = reversed * 10 + n % 10;
            n /= 10;
        }
        return (reversed < INT_MIN || reversed > INT_MAX) ? 0 : reversed;
    }
  3. 判断回文数变种

    // 判断二进制回文数
    bool isBinaryPalindrome(int n) {
        int reversed = 0, temp = n;
        while (temp) {
            reversed = (reversed << 1) | (temp & 1);
            temp >>= 1;
        }
        return n == reversed;
    }

方法二:双指针法(字符串)

代码逐行解析

bool isPalindrome(int num) {
    // 负数不是回文数
    if (num < 0) return false;
    
    // 将整数转为字符串
    string str = to_string(num);
    
    // 初始化双指针:left指向开头,right指向末尾
    int left = 0;
    int right = str.length() - 1;
    
    // 双指针向中间移动
    while (left < right) {
        // 比较左右指针指向的字符
        if (str[left] != str[right]) {
            return false;  // 发现不同,不是回文
        }
        // 移动指针
        left++;
        right--;
    }
    
    // 所有字符匹配,是回文数
    return true;
}

详细解释(新手友好)

  1. 字符串转换

    • string str = to_string(num);:将整数转为字符串

    • 例如:123 → "123"

  2. 双指针初始化

    • int left = 0;:指向字符串开头

    • int right = str.length() - 1;:指向字符串末尾

    • 例如:"123" 长度=3,right 初始为 2(索引从0开始)

  3. 双指针比较

    • while (left < right):当左指针在右指针左侧时继续

    • if (str[left] != str[right]):比较两端的字符

      • 不同:立即返回 false(不是回文)

      • 相同:继续比较

    • left++; right--;:指针向中间移动

  4. 回文判断

    • 如果所有字符都匹配,循环结束后返回 true

使用示例(同方法一)

扩展知识:双指针技巧

双指针是解决数组/字符串问题的强大工具,除了回文判断,还可用于:

  1. 两数之和

    vector<int> twoSum(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        sort(nums.begin(), nums.end());
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == target) return {left, right};
            if (sum < target) left++;
            else right--;
        }
        return {};
    }
  2. 移除元素

    int removeDuplicates(vector<int>& nums) {
        if (nums.empty()) return 0;
        int slow = 0;
        for (int fast = 1; fast < nums.size(); fast++) {
            if (nums[fast] != nums[slow]) {
                nums[++slow] = nums[fast];
            }
        }
        return slow + 1;
    }
  3. 反转字符串

    void reverseString(vector<char>& s) {
        int left = 0, right = s.size() - 1;
        while (left < right) {
            swap(s[left], s[right]);
            left++;
            right--;
        }
    }

两种方法对比

特性方法一(整数反转)方法二(双指针)
实现难度中等简单
性能高(O(log n))中(O(n))
内存使用低(常数空间)中(需字符串空间)
适用性纯数字处理也可处理字符串
溢出处理需要特别注意无此问题
新手友好中等

实际应用场景

  1. 方法一适用场景

    • 性能敏感的数值计算

    • 嵌入式系统(资源受限环境)

    • 处理大数(结合 long 或 BigInteger)

  2. 方法二适用场景

    • 快速原型开发

    • 需要同时处理字符串和数字

    • 学习算法和数据结构阶段

为什么这样写?举例说明

示例1:121(回文数)

  • 方法一

    1. 原始数:121

    2. 反转过程:0 → 1 → 12 → 121

    3. 121 == 121 → 是回文数

  • 方法二

    1. 字符串:"121"

    2. 比较:str[0] vs str[2]('1' == '1')

    3. 比较:str[1] vs str[1]('2' == '2')

    4. 所有字符匹配 → 是回文数

示例2:123(非回文数)

  • 方法一

    1. 原始数:123

    2. 反转过程:0 → 3 → 32 → 321

    3. 123 != 321 → 不是回文数

  • 方法二

    1. 字符串:"123"

    2. 第一次比较:str[0] vs str[2]('1' != '3')

    3. 立即返回 false

示例3:-121(负数)

  • 两种方法都会在第一行判断:if (num < 0) return false;

学习建议

  1. 新手学习路径

    图表

    代码

    下载

    基础语法

    方法三:双指针

    理解字符串操作

    方法一:整数反转

    掌握数值算法

  2. 练习题目

    • 基础:判断回文字符串

    • 进阶:找出范围内的所有回文数

    • 挑战:寻找回文素数(如 131)

  3. 调试技巧

    // 在方法一中添加调试输出
    while (num > 0) {
        cout << "num: " << num << " reversed: " << reversed << endl;
        reversed = reversed * 10 + num % 10;
        num /= 10;
    }

掌握这两种方法后,你不仅能解决回文数问题,还能理解更广泛的算法思想,为学习其他算法打下坚实基础。

C++ string 类型详解(新手向)

什么是 string?

string 是 C++ 标准库中提供的字符串类型,它封装了字符数组的操作,让字符串处理变得更简单、更安全。你可以把它想象成一个"智能字符数组",它会自动管理内存,并提供丰富的操作功能。

为什么需要 string?

在 C 语言中,我们使用字符数组 (char[]) 和字符指针 (char*) 来处理字符串,这需要手动管理内存,容易出现错误。C++ 的 string 解决了这些问题:

// C 语言方式(繁琐且容易出错)
char name[20];
strcpy(name, "Alice");
strcat(name, " Smith");

// C++ string 方式(简洁安全)
string name = "Alice";
name += " Smith";

基本用法

1. 包含头文件

#include <string>  // 必须包含这个头文件
using namespace std; // 或者使用 std::string

2. 创建和初始化

string s1;           // 空字符串
string s2 = "Hello"; // 直接赋值
string s3("World");  // 构造函数初始化
string s4(5, 'A');   // 创建 5 个 'A' 组成的字符串 -> "AAAAA"

3. 基本操作

string name = "Alice";

// 获取长度
int len = name.length();  // 或者 name.size()

// 访问字符
char first = name[0];      // 'A'
char last = name.at(4);    // 'e'(更安全的方式)

// 修改内容
name[0] = 'a';  // 变成 "alice"
name += " Smith"; // 字符串拼接 -> "alice Smith"

4. 输入输出

string input;

// 输入单个单词(遇到空格停止)
cout << "Enter your name: ";
cin >> input; 

// 输入整行(包含空格)
cout << "Enter your full name: ";
getline(cin, input);

5. 字符串比较

string s1 = "apple";
string s2 = "banana";

if (s1 == s2) {
    cout << "Equal";
} else if (s1 < s2) {
    cout << "apple comes before banana"; // 按字典序比较
}

在回文数判断中的应用

在我们之前的回文数判断方法三中,string 发挥了关键作用:

bool isPalindrome(int num) {
    if (num < 0) return false;
    
    // 1. 将整数转为字符串
    string str = to_string(num);
    
    // 2. 初始化双指针
    int left = 0;
    int right = str.length() - 1; // 获取字符串长度
    
    // 3. 双指针比较
    while (left < right) {
        // 比较字符
        if (str[left] != str[right]) {
            return false;
        }
        // 移动指针
        left++;
        right--;
    }
    return true;
}

关键点解析:

  1. to_string(num):将整数转换为字符串

  2. str.length():获取字符串长度

  3. str[left]:访问字符串中的字符

string 的常用功能

1. 字符串拼接

string firstName = "John";
string lastName = "Doe";

// 三种拼接方式
string fullName1 = firstName + " " + lastName;
string fullName2 = firstName;
fullName2.append(" ").append(lastName);
firstName += " ";
firstName += lastName;  // 现在 firstName 是 "John Doe"

2. 子字符串操作

string text = "Hello, World!";

// 提取子串
string greeting = text.substr(0, 5);  // "Hello"
string world = text.substr(7, 5);     // "World"

// 查找子串
size_t pos = text.find("World");  // 返回位置 7
if (pos != string::npos) {
    cout << "Found at position: " << pos;
}

// 替换子串
text.replace(7, 5, "C++");  // "Hello, C++!"

3. 字符串转换

// 数字转字符串
int age = 25;
string ageStr = to_string(age);  // "25"

// 字符串转数字
string numStr = "123";
int num = stoi(numStr);  // 123

double pi = stod("3.14159");  // 字符串转double

4. 字符串修改

string message = "I like Java";

// 插入
message.insert(7, "learning ");  // "I like learning Java"

// 删除
message.erase(7, 9);  // 删除位置7开始的9个字符 -> "I like Java"
message.erase(7);     // 删除位置7开始到结尾 -> "I like"

// 清空
message.clear();  // 空字符串

为什么在回文数判断中使用 string?

  1. 简化处理:直接操作字符比处理数字更直观

  2. 避免溢出问题:大数反转可能导致整数溢出

  3. 通用性强:同样的方法可以处理字符串回文

    bool isStringPalindrome(string str) {
        int left = 0, right = str.length() - 1;
        while (left < right) {
            if (str[left++] != str[right--]) 
                return false;
        }
        return true;
    }

内存管理(重要!)

string 自动管理内存,不需要手动分配/释放:

// 错误方式(C语言风格)
char* cstr = new char[100];
strcpy(cstr, "Hello");
delete[] cstr;  // 必须手动释放

// 正确方式(C++ string)
string s = "Hello";
// 不需要手动释放,离开作用域自动销毁

练习建议

  1. 实现一个函数,统计字符串中某个字符出现的次数

  2. 实现字符串反转函数(不使用标准库reverse)

  3. 创建一个简单的用户注册系统,验证用户名和密码格式

  4. 读取文本文件并统计单词数量

总结

string 是 C++ 中处理文本的核心工具,它:

  • 自动管理内存,使用安全

  • 提供丰富的字符串操作功能

  • 简化文本处理任务

  • 是标准库中其他组件(如文件流、正则表达式)的基础

在回文数判断中,我们利用 string 的以下特性:

  1. 数字转字符串 (to_string)

  2. 获取字符串长度 (length())

  3. 随机访问字符 ([] 或 at())

  4. 双指针遍历

掌握 string 是成为 C++ 程序员的重要一步,它能显著提高你处理文本数据的能力和效率!

注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。上述内容全是我自己理解的,如果你有别的想法,或者认为我的理解不对,欢迎指出!!!如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值