当前位置: 首页 > wzjs >正文

网站内的搜索怎么做网站运营外包公司

网站内的搜索怎么做,网站运营外包公司,公众号怎么做链接,游戏科技网站递归下降算法长用于数据表达式匹配。之前只听说和使用过递归算法,递归算法就是在函数内部调用函数本身。 在实际工作中有下边这样的需求,想不到用什么算法来实现,故将需求输入给deepseek,deepseek给出的答案中就用到了递归下降算…

递归下降算法长用于数据表达式匹配。之前只听说和使用过递归算法,递归算法就是在函数内部调用函数本身。

在实际工作中有下边这样的需求,想不到用什么算法来实现,故将需求输入给deepseek,deepseek给出的答案中就用到了递归下降算法:

在软件开发中有这样一个需求,开发语言是c++,用户可以通过配置指定任务依赖的事件,比如配置e1|e2|e3的意思是,e1、e2、e3 3个事件,只要有一个到来,那么条件就是满足的,任务可以执行;再比如,用户配置e1&e2&e3,表示,只有e1、e2、e3 3个事件都道来,任务才可以执行;在比如,用户还可以配置(2*e1 | e2) & e3,这样复杂的逻辑,表示e3是必要的,另外e1到来两次或者e2到来一次也是必要的。事件的个数不仅仅是3个,还可以更多,逻辑关系包含|表示或,&表示与,*表示时间到来的次数,逻辑关系可以任意组合。对于这样的需求,代码应该怎么实现。

递归算法:

函数内部调用函数本身,即函数a中调用函数a。

递归下降算法:

函数a调用函数b,函数b调用函数c,...函数n调用函数n+1,函数n+1调用函数a。

代码记录如下,其中类Parser中使用递归下降算法。 

#include <memory>
#include <string>
#include <map>
#include <vector>
#include <cctype>
#include <stdexcept>
#include <iostream>// ========================== 抽象语法树(AST)节点定义 ==========================
// 所有节点的基类,定义统一的评估接口
class Node {
public:virtual ~Node() = default;// 评估方法:根据当前事件状态判断条件是否满足virtual bool evaluate(const std::map<std::string, int>& events) const = 0;
};// 事件节点:表示需要特定次数的事件
class EventNode : public Node {std::string name;   // 事件名称(如"e1")int required;       // 需要达到的次数
public:EventNode(std::string n, int r) : name(std::move(n)), required(r) {}bool evaluate(const std::map<std::string, int>& events) const override {auto it = events.find(name);// 检查事件是否已到达且次数满足要求return it != events.end() && it->second >= required;}
};// 逻辑与节点:左右子节点都需要满足
class AndNode : public Node {std::unique_ptr<Node> left;   // 左子树std::unique_ptr<Node> right;  // 右子树
public:AndNode(std::unique_ptr<Node> l, std::unique_ptr<Node> r): left(std::move(l)), right(std::move(r)) {}bool evaluate(const std::map<std::string, int>& events) const override {// 递归评估左右子树是否都满足return left->evaluate(events) && right->evaluate(events);}
};// 逻辑或节点:左右子节点任一满足
class OrNode : public Node {std::unique_ptr<Node> left;   // 左子树std::unique_ptr<Node> right;  // 右子树
public:OrNode(std::unique_ptr<Node> l, std::unique_ptr<Node> r): left(std::move(l)), right(std::move(r)) {}bool evaluate(const std::map<std::string, int>& events) const override {// 递归评估左右子树是否至少有一个满足return left->evaluate(events) || right->evaluate(events);}
};// ========================== 词法分析器(Tokenizer) ==========================
// Token类型枚举
enum TokenType {NUMBER,     // 数字(用于次数)EVENT,      // 事件名称(如e1)AND,        // 与操作符 &OR,         // 或操作符 |MULTIPLY,   // 乘号 *(用于次数)LPAREN,     // 左括号 (RPAREN,     // 右括号 )END,        // 输入结束ERROR       // 错误token
};// Token结构体:包含类型、原始值和数字值(如果是数字)
struct Token {TokenType type;std::string value;  // 原始字符串值int num = 0;        // 如果是数字token,存储数值
};// 词法分析器:将输入字符串转换为token序列
class Tokenizer {std::string input;  // 原始输入字符串size_t pos = 0;     // 当前解析位置public:Tokenizer(std::string str) : input(std::move(str)) {}// 获取下一个tokenToken next() {// 跳过空白字符while (pos < input.size() && isspace(input[pos])) ++pos;if (pos >= input.size()) return {END, ""};char c = input[pos++];// 处理单字符tokenswitch(c) {case '(': return {LPAREN, "("};case ')': return {RPAREN, ")"};case '&': return {AND, "&"};case '|': return {OR, "|"};case '*': return {MULTIPLY, "*"};}// 处理数字(次数)if (isdigit(c)) {size_t start = pos-1;while (pos < input.size() && isdigit(input[pos])) ++pos;int num = std::stoi(input.substr(start, pos-start));return {NUMBER, "", num};}// 处理事件名称(字母开头,包含字母数字和下划线)if (isalpha(c)) {size_t start = pos-1;while (pos < input.size() && (isalnum(input[pos]) || input[pos] == '_')) ++pos;return {EVENT, input.substr(start, pos-start)};}// 未知字符return {ERROR, ""};}
};// ========================== 语法分析器(Parser) ==========================
// 递归下降解析器:将token流转换为AST
class Parser {Tokenizer& tokenizer;  // 词法分析器引用Token current;         // 当前处理的token// 前进到下一个tokenvoid advance() { current = tokenizer.next(); }// 表达式解析(处理OR操作)std::unique_ptr<Node> parseExpr() {auto left = parseAnd();// 循环处理连续的OR操作(左结合)while (current.type == OR) {advance(); // 跳过ORauto right = parseAnd();// 构建OR节点,左子树为之前的表达式,右子树为新的AND表达式left = std::make_unique<OrNode>(std::move(left), std::move(right));}return left;}// AND表达式解析(处理AND操作)std::unique_ptr<Node> parseAnd() {auto left = parseTerm();// 循环处理连续的AND操作(左结合)while (current.type == AND) {advance(); // 跳过ANDauto right = parseTerm();// 构建AND节点left = std::make_unique<AndNode>(std::move(left), std::move(right));}return left;}// 项解析(处理次数*事件格式)std::unique_ptr<Node> parseTerm() {// 检查是否是数字开头(次数定义)if (current.type == NUMBER) {int count = current.num;advance(); // 跳过数字if (current.type != MULTIPLY) throw std::runtime_error("Expected * after number");advance(); // 跳过*if (current.type != EVENT) throw std::runtime_error("Expected event after *");// 创建带次数的事件节点auto node = std::make_unique<EventNode>(current.value, count);advance(); // 跳过事件名return node;}return parseFactor();}// 因子解析(处理括号和基本事件)std::unique_ptr<Node> parseFactor() {if (current.type == LPAREN) {advance(); // 跳过(auto node = parseExpr(); // 递归解析括号内表达式if (current.type != RPAREN)throw std::runtime_error("Mismatched parentheses");advance(); // 跳过)return node;}if (current.type == EVENT) {// 创建默认次数为1的事件节点auto node = std::make_unique<EventNode>(current.value, 1);advance(); // 跳过事件名return node;}throw std::runtime_error("Unexpected token");}public:Parser(Tokenizer& t) : tokenizer(t) { advance(); } // 初始化时获取第一个tokenstd::unique_ptr<Node> parse() {return parseExpr();}
};// ========================== 使用示例 ==========================
int main() {// 示例1: (2*e1 | e2) & e3{std::cout << "===== 测试用例1 =====" << std::endl;std::string config = "(2*e1 | e2) & e3";Tokenizer tokenizer(config);Parser parser(tokenizer);auto ast = parser.parse();// 测试用例1:e1触发2次,e3触发1次 -> 应满足std::map<std::string, int> case1 = {{"e1", 2}, {"e3", 1}};  std::cout << "Case1: " << ast->evaluate(case1) << " (预期: true)\n";// 测试用例2:e2触发1次,e3触发1次 -> 应满足std::map<std::string, int> case2 = {{"e2", 1}, {"e3", 1}};   std::cout << "Case2: " << ast->evaluate(case2) << " (预期: true)\n";// 测试用例3:e1触发1次,e3触发1次 -> 不满足std::map<std::string, int> case3 = {{"e1", 1}, {"e3", 1}};  std::cout << "Case3: " << ast->evaluate(case3) << " (预期: false)\n";}// 示例2: a | b&(c | 3*d){std::cout << "\n===== 测试用例2 =====" << std::endl;std::string config = "a | b&(c | 3*d)";Tokenizer tokenizer(config);Parser parser(tokenizer);auto ast = parser.parse();// 测试用例1:a触发1次 -> 应满足std::map<std::string, int> case1 = {{"a", 1}};                 std::cout << "Case1: " << ast->evaluate(case1) << " (预期: true)\n";// 测试用例2:b触发1次,d触发3次 -> 应满足std::map<std::string, int> case2 = {{"b",1}, {"d",3}};         std::cout << "Case2: " << ast->evaluate(case2) << " (预期: true)\n";// 测试用例3:b触发1次,c触发1次 -> 应满足std::map<std::string, int> case3 = {{"b",1}, {"c",1}};         std::cout << "Case3: " << ast->evaluate(case3) << " (预期: true)\n";// 测试用例4:b触发1次,d触发2次 -> 不满足std::map<std::string, int> case4 = {{"b",1}, {"d",2}};         std::cout << "Case4: " << ast->evaluate(case4) << " (预期: false)\n";}return 0;
}


文章转载自:

http://IkFVl0kM.tkqzr.cn
http://88FtEfxy.tkqzr.cn
http://XEuBs42w.tkqzr.cn
http://o2ad1nVn.tkqzr.cn
http://Ht8nRlMD.tkqzr.cn
http://Br0u5Hht.tkqzr.cn
http://CPMIzpTC.tkqzr.cn
http://TnPzPzo9.tkqzr.cn
http://EFaZRynV.tkqzr.cn
http://J6IMVZBM.tkqzr.cn
http://I1eLbiAe.tkqzr.cn
http://DNxE1CkO.tkqzr.cn
http://8vxrJPTF.tkqzr.cn
http://SMTmoVqg.tkqzr.cn
http://wRGGO3F3.tkqzr.cn
http://AOIvQy1m.tkqzr.cn
http://Jobc0gsZ.tkqzr.cn
http://ig7lk4N7.tkqzr.cn
http://FMfeuXId.tkqzr.cn
http://2kLMXnXP.tkqzr.cn
http://QUN7f4sK.tkqzr.cn
http://B9FQK6Fb.tkqzr.cn
http://K2kpUeh7.tkqzr.cn
http://hJVfoSlT.tkqzr.cn
http://eSrXvQig.tkqzr.cn
http://R8sMZeH2.tkqzr.cn
http://LMZQylSQ.tkqzr.cn
http://2z73umM9.tkqzr.cn
http://C975vmep.tkqzr.cn
http://EWpgUMoj.tkqzr.cn
http://www.dtcms.com/wzjs/659303.html

相关文章:

  • 做设计图任务的网站网站的后台地址
  • 什么是单页网站制作相册影集的软件
  • physon可以做网站温州网站建设案例
  • 建设优化网站wordpress自媒体主题ming
  • 西咸新区建设环保网站wordpress+教材主题
  • 大连做网站需要多少钱Wordpress一直刷不出
  • 国内做网站最大的公司注册网站域名有什么用
  • 自己做网站自己做SEO电销
  • 哪里有做兼职的网站东莞网站建设公司电话
  • 齐齐哈尔建设网站dw怎么做网站
  • 做网站能传电影网站多少钱深圳10大品牌策划公司
  • 商城购物网站有哪些模块装修设计案例网站
  • 深圳市门户网站建设多少钱深圳公司画册设计
  • 广州白云发布通告seo关键词怎么选
  • phpcms v9网站导航网站首页尺寸
  • 如何通过外链提高网站权重wordpress结算加载太慢
  • php和django做网站哪个好河曲县城乡建设管理局网站
  • 网站备案一次吗ps里新建网站尺寸怎么做
  • 淄博做网站封面制作app
  • 上海平台网站建设哪家好修改wordpress登陆用户名和密码
  • 保定网站制作套餐肇庆seo按天收费
  • 新乡网站seo优化手机网站开发 手机模拟器
  • 个人网站维护费用营销型电子商务网站
  • 上传到网站的根目录中wordpress怎么更新缓存
  • 嘉兴市城市建设门户网站陕西省住建厅网站官网
  • 企业公司网站 北京贵阳网站设计公司价格
  • 深圳品牌营销网站建设国外网页素材网站
  • 企业门户网站的主要论点及写作体会怎么写虚拟主机 两个网站
  • 要找人做公司网站应该怎么做建立了公司门户网站
  • 做网站制作课程总结赣州市网站建设