我有这样的表达式:
(猫或猫或小猫或小猫)和(狗或狗)NOT(鸽子或萤火虫)
任何人都知道如何制作表来保存它们?
在我收到使用括号的请求之前,我限制了操作符的使用以避免模糊的情况。所以只有AND和NOT或只有OR并以这种方式保存它们:
运营商
id | name
1 | AND
2 | OR
3 | NOT
关键字的
id | keyword
1 | cat
2 | dog
3 | firefly
表达式
id | operator | keywordId
1 | 0 | 1
1 | 1 | 2
1 | 3 | 3
这是:猫和狗不是萤火虫
但现在,我真的很困惑......
答案 0 :(得分:3)
将它们保存为字符串或序列化数据结构(例如,解析树)很可能是最佳解决方案,除非您确实需要修改数据库本身的表达式部分。
答案 1 :(得分:3)
我会以文本格式将它们存储为reverse Polish,并使用空格将操作符/操作数存储为空白,例如:
cat cats OR dog dogs OR AND
pigeon firefly OR NOT
这允许您非常简单地实现布尔表达式求值器,并且我认为这是您想要的。
如果你想让它更容易评估,我会将对象名称的绑定存储到一个小词汇表(例如A-Z)和AND,OR,NOT的类似词汇表中:
cat A cats B dog C dogs : DAB+CD+&
pigeon A firefly : AB+~
然后基本的表达式求值程序只需处理不变的字符,并且非常容易编码。
答案 2 :(得分:2)
在过去的这种情况下,我创建了一个整数列,可以执行按位操作。说明如下:
首先为每个值分配一个二进制数字 -
Cat Dog Firefly
--- --- ------
1 2 4
接下来,您将向主表添加一个整数列,我们将其称为选项。当数字转换为二进制时,每个数字将代表天气猫,狗或萤火虫是允许的。例如:
5 = 101二进制=允许猫,不允许狗,允许萤火虫。
id | locationName | options
---------------------------
1 | loc 1 | 5
2 | loc 2 | 2
3 | loc 3 | 7
4 | loc 4 | 6
我们现在可以对options列使用按位运算来确定允许的选项。例子:
要获取所有允许狗的记录,当我们不涉及猫或萤火虫时,您将执行以下按位操作:
2& options = 2
这将返回记录2,3和4。
要获得允许狗和萤火虫的所有记录,我们将按照按位操作执行:
6& options = 6
这将返回记录3和4
要获取允许猫和萤火虫的所有记录,我们将执行以下按位操作:
5& options = 5
这将返回记录1和3。
只接受萤火虫:
4 |选项= 4
不接受萤火虫:
4& options = 0
这可能是一个难以掌握的概念,所以如果您有任何疑问,请告诉我。在我看来,一旦掌握了这个概念,它可能是完成你想要做的事情的最简单方法。
答案 3 :(得分:0)
我认为你需要有可能连接“子表达式”。为什么表连接自身(到父表达式)的表达式中没有可空的外键?
答案 4 :(得分:0)
(猫或猫)和(狗或狗)NOT(鸽子或萤火虫)
和
猫与狗不是萤火虫
作为NOT的无效布尔表达式都是一元运算符(它只需要1个操作数)。
话虽如此,这是一个艰难的过程。在数据库级别进行本地化是很困难的。嗯..下面想到:
表达式
ID |运算符|关键字1 |关键字2 |表达式1 |表达式2
所以这里,keyword1,keyword2,expression1和expression2都可以为空,每个表达式都存储为关键字或其他表达式的一元操作,或者对0,1或2个关键字和0,1的二进制操作, 2其他表达。每个表达式1条记录,包含所有子表达式的附加记录。您可以递归地完成代码中的评估。
这样你就不会有重复的ID。我看到的唯一缺点是很难保存像(猫和猫)和狗与猫和猫(猫和狗)这样的东西。这两个都评估相同,但计算顺序发生变化。
很确定这会奏效。如果您需要更多详细信息,请在评论中与我联系。
普拉门