You need to enable JavaScript to run this app. C++成绩评级系统中switch适配字符串及带加减后缀成绩输出异常咨询
优惠活动
大模型
产品
解决方案
定价
更多

C++成绩评级系统中switch适配字符串及带加减后缀成绩输出异常咨询

C++ 成绩评级系统问题修复

现有代码核心问题清单

  • 自定义string_hash方案不适配当前业务:原哈希函数对多字符成绩串(如A+)的计算结果,与单字符后缀(+/-)的哈希值完全不匹配,后续switch分支永远无法命中;同时原哈希的位移逻辑容易出现碰撞和溢出,不同字符串可能生成相同哈希值。
  • 后缀判断的if条件语法错误:if (atzime[1] == '-' || '+')中,||后的+是常量非0,等价于永远为真,哪怕输入只有单个字母(如A)也会进入分支,越界访问atzime[1]触发未定义行为。
  • 逻辑顺序混乱:基础成绩分支提前输出结果,后续后缀计算完成后没有复用调整后的值,甚至会重复输出。
  • 变量赋值未生效:计算完pluss/minuss后,输出的仍是原始atzime_sk,没有把调整后的值赋值给输出变量。

针对成绩系统的简化修复方案

你当前的业务场景不需要对整个成绩字符串做switch,仅需判断首字母和后缀字符即可,完全可以去掉冗余的字符串哈希逻辑,修复后核心代码如下:

#include <iostream>
#include <string> 

using std::cin;
using std::cout;
using std::string;

int main() {
    cout << "Ievadiet atzimi ar burtiem (A, B, C, D, F) ==> ";
    string atzime;
    cin >> atzime;

    // 输入合法性校验
    if (atzime.empty() || atzime.size() > 2) {
        cout << "Nederiga atzime!";
        return 1;
    }

    char burts = atzime[0];
    double atzime_sk;

    // 先计算基础成绩,不提前输出
    switch(burts) 
    {
    case 'A': atzime_sk = 4; break;
    case 'B': atzime_sk = 3; break;
    case 'C': atzime_sk = 2; break;
    case 'D': atzime_sk = 1; break;
    case 'F': atzime_sk = 0; break;
    default:
        cout << "Nederiga atzimes burts!";
        return 1;
    }

    // 修正后缀判断逻辑:先校验长度,再判断字符
    if (atzime.size() == 2) {
        char piedeva = atzime[1];
        // F等级无+/-,单独处理边界
        if (burts != 'F') {
            if (piedeva == '+') {
                atzime_sk += 0.3;
            } else if (piedeva == '-') {
                atzime_sk -= 0.3;
            } else {
                cout << "Nederiga piedeva!";
                return 1;
            }
        }
    }

    // 统一输出最终成绩
    cout << "Tava atzime ir ==> " << atzime_sk;
    return 0;
}

如果仍需要实现字符串switch的可行哈希方案

如果你后续确实需要用switch匹配字符串类型,原自定义哈希需要替换为编译期可校验、低碰撞的实现(如FNV-1a哈希),示例如下:

// 编译期FNV-1a哈希,低碰撞率
constexpr long long string_hash(const char *s) {
    long long hash = 0xcbf29ce484222325; // FNV偏移基值
    while (*s) {
        hash ^= static_cast<long long>(*s++);
        hash *= 0x100000001b3; // FNV质数
    }
    return hash;
}

constexpr long long operator"" _sh(const char *s, size_t) {
    return string_hash(s);
}

// 用法示例(需匹配完整字符串,如"A+"_sh)
switch (string_hash(atzime.c_str())) {
    case "A+"_sh: cout << "A+"; break;
    case "A-"_sh: cout << "A-"; break;
    // 其他成绩分支
}

注意:该方案仅适合已知少量固定字符串的场景,编译期可通过静态断言校验哈希碰撞,运行时仍需注意极端场景的冲突处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 21:36:05