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

C++中解析状态字符串并填充状态转换信息的技术问题

C++ 解析状态机格式字符串实现修正

问题需求

需要解析特定格式的字符串,生成包含输入触发条件及对应跳转目标状态的状态信息。现有代码无法正确提取状态名称(会包含n{前缀),且无法提取转换信息,需修正实现。

示例输入字符串

i{OPEN}a{LOCKED}s{n{OPEN}t{i{PUSH}d{CLOSED}}t{i{PULL}d{OPEN}}t{i{TURN}d{OPEN}}}s{n{CLOSED}t{i{PUSH}d{CLOSED}}t{i{PULL}d{OPEN}}t{i{TURN}d{LOCKED}}}s{n{LOCKED}t{i{PUSH}d{LOCKED}}t{i{PULL}d{LOCKED}}t{i{TURN}d{CLOSED}}}

格式规则

  • s{...}表示一个状态,所有状态信息位于大括号内
  • n{xxx}表示状态名称为xxx,嵌套在s{}中
  • t{...}表示状态转换规则,一个状态可包含多个t{}块
  • t{}内的i{xxx}是触发转换的输入值,d{xxx}是跳转的目标状态,二者顺序不固定
  • i{xxx}表示初始状态名称,a{xxx}表示接受状态名称,二者可出现在字符串任意位置(包括s{}外)

修正后的代码实现

类定义

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

// 转换规则类
struct Transition {
    std::string input;
    std::string targetState;
};

// 状态类
struct State {
    std::string name;
    std::vector<Transition> transitions;
};

// 全局状态机信息
std::unordered_map<std::string, State> states;
std::string initialState;
std::string acceptState;

解析核心函数

// 辅助函数:提取大括号内的纯内容,同时移动迭代器到闭合括号后
std::string extractBracketContent(std::string::iterator& it) {
    std::string content;
    ++it; // 跳过开头的'{'
    int bracketCount = 1;
    while (it != content.end() && bracketCount > 0) {
        if (*it == '{') {
            bracketCount++;
        } else if (*it == '}') {
            bracketCount--;
            if (bracketCount == 0) {
                ++it; // 跳过闭合的'}'
                break;
            }
        }
        content += *it;
        ++it;
    }
    return content;
}

// 解析状态机字符串
void parseAndPopulateStates(const std::string& inputStr) {
    auto it = inputStr.begin();
    while (it != inputStr.end()) {
        if (*it == 'i') {
            // 提取初始状态
            ++it;
            initialState = extractBracketContent(it);
        } else if (*it == 'a') {
            // 提取接受状态
            ++it;
            acceptState = extractBracketContent(it);
        } else if (*it == 's') {
            // 解析单个状态块
            ++it;
            std::string stateContent = extractBracketContent(it);
            auto stateIt = stateContent.begin();
            State currentState;

            while (stateIt != stateContent.end()) {
                if (*stateIt == 'n') {
                    // 提取纯状态名称
                    ++stateIt;
                    currentState.name = extractBracketContent(stateIt);
                } else if (*stateIt == 't') {
                    // 解析单条转换规则
                    ++stateIt;
                    std::string transContent = extractBracketContent(stateIt);
                    auto transIt = transContent.begin();
                    Transition trans;

                    while (transIt != transContent.end()) {
                        if (*transIt == 'i') {
                            ++transIt;
                            trans.input = extractBracketContent(transIt);
                        } else if (*transIt == 'd') {
                            ++transIt;
                            trans.targetState = extractBracketContent(transIt);
                        } else {
                            // 跳过空格等无关字符
                            ++transIt;
                        }
                    }
                    currentState.transitions.push_back(trans);
                } else {
                    // 跳过空格等无关字符
                    ++stateIt;
                }
            }
            states[currentState.name] = currentState;
        } else {
            // 跳过空格等无关字符
            ++it;
        }
    }
}

测试与输出函数

// 打印解析结果
void printStateMachine() {
    std::cout << "初始状态: " << initialState << std::endl;
    std::cout << "接受状态: " << acceptState << std::endl;
    std::cout << "\n状态转换信息:" << std::endl;
    for (const auto& pair : states) {
        const State& state = pair.second;
        std::cout << "\n状态: " << state.name << std::endl;
        for (const Transition& trans : state.transitions) {
            std::cout << "  输入[" << trans.input << "] -> 目标状态[" << trans.targetState << "]" << std::endl;
        }
    }
}

int main() {
    std::string input = "i{OPEN}a{LOCKED}s{n{OPEN}t{i{PUSH}d{CLOSED}}t{i{PULL}d{OPEN}}t{i{TURN}d{OPEN}}}s{n{CLOSED}t{i{PUSH}d{CLOSED}}t{i{PULL}d{OPEN}}t{i{TURN}d{LOCKED}}}s{n{LOCKED}t{i{PUSH}d{LOCKED}}t{i{PULL}d{LOCKED}}t{i{TURN}d{CLOSED}}}";
    parseAndPopulateStates(input);
    printStateMachine();
    return 0;
}

关键修正点

  1. 纯内容提取:通过辅助函数extractBracketContent直接获取{}内部的纯文本,彻底解决状态名称携带n{前缀的问题。
  2. 转换规则兼容:遍历t{}内容时分别提取i{}和d{}的值,支持二者任意顺序。
  3. 鲁棒性处理:添加对空格等无关字符的跳过逻辑,避免解析流程中断。
  4. 嵌套括号兼容:辅助函数通过括号计数处理嵌套场景,兼容更复杂的输入格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:04:51