You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于string类at成员函数、out_of_range异常及异位字符串判断问题

关于字母异位词判断代码与string::at异常处理的问题

您好!我看到您的母语不是英语,没关系,咱们一步步来解决您的问题~

一、字母异位词判断函数的问题分析

您的LetterChange函数逻辑存在几个关键问题,会导致它无法正确判断字母异位词:

  • 循环逻辑漏洞:当找到s1[i]和s2[j]匹配后,您仅增加了i和计数k,但没有标记s2[j]为已使用。这会导致s2中的同一个字符被重复匹配,比如s1="aab"、s2="aba"时,会出现错误的匹配计数。
  • 重复字符处理失效:对于包含重复字母的字符串,您的方法无法准确统计字符出现的次数,最终会返回错误结果。

改进后的字母异位词实现方案

这里提供两种高效且可靠的实现方法:

方法1:排序对比法

将两个字符串排序后,若为字母异位词则排序结果完全相同,同时需确保原字符串不相等:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

bool LetterChange(string s1, string s2) {
    // 先排除长度不同或原字符串相同的情况
    if (s1.size() != s2.size() || s1 == s2) {
        return false;
    }
    // 对两个字符串排序
    sort(s1.begin(), s1.end());
    sort(s2.begin(), s2.end());
    // 排序后相等则是字母异位词
    return s1 == s2;
}

int main() {
    string s1, s2;
    cin >> s1;
    cin >> s2;
    cout << (LetterChange(s1, s2) ? "ok" : "not ok") << endl;
    return 0;
}

方法2:字符计数法

通过数组统计每个字符的出现次数,对比两个字符串的字符分布是否一致:

#include<iostream>
#include<string>
using namespace std;

bool LetterChange(string s1, string s2) {
    if (s1.size() != s2.size() || s1 == s2) {
        return false;
    }
    // 假设仅处理小写字母,若包含大写可调整数组范围或统一转换大小写
    int charCount[26] = {0};
    // 统计s1的字符出现次数
    for (char c : s1) {
        charCount[c - 'a']++;
    }
    // 用s2的字符抵消计数,中途出现负数直接返回false
    for (char c : s2) {
        charCount[c - 'a']--;
        if (charCount[c - 'a'] < 0) {
            return false;
        }
    }
    // 检查所有字符计数是否归零
    for (int count : charCount) {
        if (count != 0) {
            return false;
        }
    }
    return true;
}

int main() {
    string s1, s2;
    cin >> s1;
    cin >> s2;
    cout << (LetterChange(s1, s2) ? "ok" : "not ok") << endl;
    return 0;
}

二、string::at的out_of_range异常处理

string::at会在访问索引超出字符串长度范围时抛出std::out_of_range异常(而[]运算符不会做边界检查,会导致未定义行为)。如果需要处理该异常,可以用try-catch块包裹调用代码:

异常处理示例

#include<iostream>
#include<string>
#include<stdexcept>
using namespace std;

int main() {
    string testStr = "hello";
    try {
        // 尝试访问超出范围的索引
        char c = testStr.at(10);
        cout << c << endl;
    } catch (const out_of_range& e) {
        // 捕获异常并输出错误信息
        cerr << "异常提示:" << e.what() << endl;
    }
    return 0;
}

注意事项

  • 在您原来的代码中,i和j的循环范围都被限制在字符串长度内(i < s1.size()、j < s2.size()),所以at函数不会抛出异常,这种场景下无需额外处理。
  • 只有当您无法提前确认索引合法性时,才需要添加try-catch进行异常捕获。

希望这些解释和改进能帮到您!如果还有其他问题,欢迎继续提问~

内容的提问来源于stack exchange,提问作者GPLUSVABLE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:06:21