如何使用一组数字和运算符生成所有可能的方程式?

时间:2013-05-18 16:26:40

标签: algorithm

我遇到了数学和编程问题。

给定一组字符{1,2,3,4,5,6,7,8,9,+,-,*,/}。然后使用这组字符在数组中随机生成10(或者说N)个字符,即[1,+,1,∗,3,5,7,8,1]。在那之后,我需要通过使用这个字符数组加上1个字符'='来找到方程式的所有可能性。

因此,在这种情况下,[1,+,1,∗,3,5,7,8,1]类似于以下等式:1*1=13+5=87+1=815=8+715+3=18 (也许更多)

它可以形成多位数操作,即15+3=18

所以我的问题是我正在尝试使用程序生成所有方程式。你能不能给我一些想法,哪种算法可以做到?或任何方法吗?

我目前的做法:

我的方法不够快。所以这个想法是,最小等式需要3个数和1个算子。和

  1. 我从生成的数组中随机选择4个成员开始。如果这4个成员有一个运营商,
  2. 然后我会添加'='
  3. 形成所有可能的订单。例如1,1,2,+,我将有112 + =,121 + =,1 = 12 + ....循环所有这些。和
  4. 然后增加到5个成员并循环通过它......
  5. 直到生成数组的长度

2 个答案:

答案 0 :(得分:4)

正如评论中已经提到的,这似乎是NP完全的,因此是指数级的,因此它需要真正长,但这就是我要做的事情:

对于输入的每个可能的子集A执行以下操作:

生成A的所有排列。

所以每个排列都对应一个方程式(或者那个类似于方程的东西,但没有=符号)。

现在请注意,会出现很多无效的'等式'。像1**1这样的事情。你需要忽略所有这些。粗略地说,任何以运算符开头或结尾或连续使用2个运算符的任何内容都是无效的(或者可能不是1*-2-2+11--1(?)是有效的({{1} }和1++1?),但无论如何,我相信你可以解决问题。)

对于每个有效的排列,将评估得到的数字加到一个集合中(好的,一个(多个)数字地图到公式)。

当从输入中删除A时,对剩余项目的所有排列执行相同操作(导致另一个生成集)。

现在,两组中出现的所有数字都是有效的方程式。请注意(由于缺乏解释的愿望),您将对所有具有相同数字的方程式进行CROSS JOIN类似的处理。

我们只生成了两次,一次在左侧,一次在右侧?哎呦。好的,这是一个修复:“为包含该元素的输入的每个可能的子集A选择任何元素......”。

要考虑的事情 - 分离出运营商

优势:可能要快得多(不太确定,甚至可能会慢一些)
缺点:这是更复杂的

预处理输入,删除所有操作符,只需对每个操作符进行计数。

与上面完全相同,但是,对于每个排列,还会生成运算符可以去的所有排列。如果做得好,你应该能够完全避免无效的方程式。

并且还有多个设置来放入数字(所以你将有2套),每个可能允许的每种类型的操作数一个,然后你将与另一组进行比较(在另一组中)一组集合),以便使用所有运算符。

用一个例子来解释:

输入:+1+2

没有操作员的输入:[1,*,1,3,5,7,8,+,+,1]

算:

[1,1,3,5,7,8,1]

示例子集:Operator Count + 2 * 1
它的补充:[1,7,8,1]

现在我们将拥有2x6套,每套可能的运营商组合一套:

[1,3,5]

以上只是示例,显然每个集合中有多于1个等式,您需要考虑运营商可以去的所有地方,例如,考虑 ++* ++ +* + * 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*78 +1+17*8 +11+7*8 1+1+7*8 1*1+7+8 1+1*7+8 etc. 和补集的1178,但是需要添加所有排列(即1187,1718,1781,......和315,513) ,531,......)。

一旦将所有这些添加到集合中,您将按如下方式匹配集合,因此我们使用等式中的所有运算符:

351

为了更好地了解发生的事情,并假设我们在数学上非常糟糕,我们可以说:(取自上面的网格)

Subset      Complement
++*    with NONE
++     with *
+*     with +
+      with +*
*      with ++
NONE   with ++*

现在,您将使用其评估的值匹配方程式(使用有序集将允许您在线性时间内同时逐步执行这两个方程)。所以,假设子集的方程A和B都评估为79,补语的方程C和D也评估为79.现在你将它们匹配如下:(这就是我所说的CROSS JOIN)< / p>

+1*1+78 = 351
11+7+8 = 3*51
1*1+78 = 35+1
etc.

以及(如果你想要这些):

A = C
A = D
B = C
B = D

我希望澄清它。

答案 1 :(得分:0)

作为使用上面的示例集的解决方案的原始黑客,一个算法将直接找到所选数字,运算符和=的所有组合,并且测试例如。

  • 所有变体中的所有9加上=(10个字符)。数量为10×9×8×7×6×5×4×3×2×1 = 10! = 3,628,800个变体。
  • 然后在所有变体中加上8加=(9个字符)。 10×9×8×7×6×5×4×3×2 = 10!÷1!
  • 然后在所有变体中加上7加=(8个字符)。 10×9×8×7×6×5×4×3 = 10!÷2!
  • 等等,直到4加上=(3个数字和2个运算符= 5个字符)的所有变体。 10×9×8×7×6 = 10!÷5!

此等式为(n+1)!÷0! + (n+1)!÷1! + ... + (n+1)!÷(n-4)!

  • 其中n是生成的数字和运算符减去=。

在您的示例中,将存在 9,858,240 潜在等式。值得注意的是,将存在无效的等式,其中=在末端,=和一个运算符在一起等等。所以我是积极的,可以存在更好的。

  • 排除结尾的=将减少1,971,648