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

如何为调度场算法实现分词器与Token向量?C++ RPN计算器开发求助

关于RPN计算器中枚举类、分词器与Token向量的解释

一、枚举类(enum class)在该场景的核心作用

C++的enum class是强类型枚举,和普通枚举相比,它不会隐式转换为整数,也不会污染全局命名空间,特别适合给计算器的Token做类型标记。比如你需要区分数字、运算符、函数、括号等不同类型的输入单元,用枚举类能清晰划分每种Token的类别:

enum class TokenType {
    Number,
    Plus,
    Minus,
    Sin,
    Gcf,
    Mean,
    LeftParen,
    RightParen,
    End
};

这种方式替代了用魔法数字(比如用0代表数字、1代表加号)的混乱写法,后续处理调度场算法时,判断Token类型的逻辑会更清晰、不易出错。

二、Token向量与分词器的关联逻辑

首先,Token不是单纯的枚举值,它是一个包含类型和对应数据的结构体,示例如下:

struct Token {
    TokenType type;
    double value; // 存储数字值,非数字Token可忽略
    std::string func_name; // 存储函数名,比如"sin""mean"
};

Token向量就是std::vector<Token>,用来存储分词器拆分后的所有Token单元——相当于把输入字符串(比如"3 sin 4 + gcf(5,10)")拆成一个个有明确类型的独立单元,方便调度场算法直接处理。

分词器的核心工作就是把输入字符串拆分为上述Token序列,基本逻辑如下:

  • 遇到数字/小数点:读取连续的数字字符,转换为double类型,生成TokenType::Number类型的Token,把数值存入value字段。
  • 遇到字母:读取连续的字母,判断是sin/gcf/mean等函数名,生成对应类型的Token,把函数名存入func_name字段。
  • 遇到运算符/括号:直接生成对应类型的Token。

简单的分词逻辑片段示例:

std::vector<Token> tokenize(const std::string& input) {
    std::vector<Token> tokens;
    size_t i = 0;
    while (i < input.size()) {
        if (std::isdigit(input[i]) || input[i] == '.') {
            // 处理数字
            size_t j = i;
            while (j < input.size() && (std::isdigit(input[j]) || input[j] == '.')) j++;
            double num = std::stod(input.substr(i, j - i));
            tokens.push_back({TokenType::Number, num, ""});
            i = j;
        } else if (std::isalpha(input[i])) {
            // 处理函数名
            size_t j = i;
            while (j < input.size() && std::isalpha(input[j])) j++;
            std::string name = input.substr(i, j - i);
            TokenType type;
            if (name == "sin") type = TokenType::Sin;
            else if (name == "gcf") type = TokenType::Gcf;
            else if (name == "mean") type = TokenType::Mean;
            tokens.push_back({type, 0.0, name});
            i = j;
        } else {
            // 处理运算符与括号
            switch(input[i]) {
                case '+': tokens.push_back({TokenType::Plus, 0.0, ""}); break;
                case '-': tokens.push_back({TokenType::Minus, 0.0, ""}); break;
                case '(': tokens.push_back({TokenType::LeftParen, 0.0, ""}); break;
                case ')': tokens.push_back({TokenType::RightParen, 0.0, ""}); break;
            }
            i++;
        }
    }
    tokens.push_back({TokenType::End, 0.0, ""});
    return tokens;
}

三、适合的学习资源

书籍

  • 《C++ Primer》:对枚举类、结构体、容器等C++核心语法讲解细致,适合新手循序渐进掌握基础。
  • 《算法导论》:包含调度场算法的详细逻辑,能帮你理解如何将Token序列转换为RPN表达式并计算结果。
  • 《C++ Cookbook》:有大量实用代码示例,涵盖字符串处理、容器使用等场景,可快速参考写出可用的分词器。

学习步骤建议

  1. 先吃透enum class的基础:包括定义方式、取值逻辑、与普通枚举的差异。
  2. 先实现简单分词器:只处理数字和基础运算符,验证Token向量生成的正确性。
  3. 逐步扩展功能:添加函数、括号的处理逻辑,最后结合调度场算法完成RPN计算器的核心流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:22:31