正如评论中已经提到的,这似乎是 NP 完全的,因此是指数级的,因此需要很长时间,但这仍然是我要做的:
对于输入的每个可能的子集 A,请执行以下操作:
生成 A 的所有排列。
所以每个排列都对应一个方程(或者那个像方程但没有=
符号的东西)。
现在请注意,会有很多无效的“方程式”。之类的东西1**1
。您需要在进行时忽略所有这些。几乎任何以一个运算符或连续 2 个运算符开始或结束的东西都是无效的(或者可能不是,1*-2
和-2+1
( 1--1
?) 是有效的(1++1
和+1+2
?),但无论如何,我相信你能弄清楚)。
对于每个有效的排列,将评估它得到的数字添加到一个集合(嗯,一个(多)数字到方程的映射)。
当从输入中删除 A 时(导致另一个生成的集合),对剩余项目的所有排列执行相同的操作。
现在出现在两组中的所有数字都是有效的方程。请注意(因为不想解释)您将对所有具有相同编号的方程执行类似CROSS JOIN的过程。
我们是否只生成了每个集合两次,一次在左侧,一次在右侧?哎呀。好的,这是一个修复:“为包含该元素的输入的每个可能的子集 A 选择任何元素......”。
需要考虑的事情 - 分离运营商
优点:可能快很多(不太确定,甚至可能更慢)
缺点:复杂很多
预处理输入,删除所有运算符,然后简单地计算每个运算符。
执行与上面完全相同的操作,但是对于每个排列,还生成运算符可以去哪里的所有排列。如果做得对,您应该能够完全避免无效的方程式。
并且还有多个集合可以放入数字(因此您将有 2 组集合),一个用于允许的每种类型的运算符的每个可能数量,然后您将与另一组进行比较(在另一组集合中) ) 使得所有运算符的数量都被使用。
用一个例子来解释:
输入:[1,*,1,3,5,7,8,+,+,1]
不带运算符的输入:[1,1,3,5,7,8,1]
运营商:
Operator Count
+ 2
* 1
一个示例子集:[1,7,8,1]
它的补充:[1,3,5]
现在我们将有 2x 6 个集合,一个用于两个集合的可能运算符的每种组合:
++* ++ +* + * NONE
Subset +1*1+78 11+7+8 1*1+78 117+8 1*178 1178
Complement +3*5+1 3+5+1 3*5+1 35+1 3*51 351
以上只是示例,每个集合显然不止1个方程,您需要考虑运算符可以去的任何地方,例如,考虑++*
:
+1+1*78
+1+17*8
+11+7*8
1+1+7*8
1*1+7+8
1+1*7+8
etc.
而且我只考虑了1178
示例和351
补码的排列,但所有排列都需要添加(即 1187、1718、1781、...和 315、513、531、...)。
将所有这些都添加到集合后,您可以按如下方式匹配集合,因此我们在等式中使用所有运算符:
Subset Complement
++* with NONE
++ with *
+* with +
+ with +*
* with ++
NONE with ++*
为了更好地了解会发生什么,并假设我们的数学真的很差,我们可以说:(取自上面的网格)
+1*1+78 = 351
11+7+8 = 3*51
1*1+78 = 35+1
etc.
现在,您将使用它计算的值来匹配方程(使用排序集将允许您在线性时间内同时逐步完成这两个)。所以,假设子集的方程 A 和 B 都计算为 79,补码的方程 C 和 D 也计算为 79。现在你将它们匹配如下:(这就是我所说的 CROSS JOIN)
A = C
A = D
B = C
B = D
还有(如果你想要这些):
C = A
C = B
D = A
D = B
我希望能澄清它。