解决给定数字集中的所有可能表达式

时间:2014-02-27 06:32:24

标签: c++ algorithm expression

最近我遇到了一个类似这样的问题。您将获得n个号码和三个运算符+-*。使用第一个n-1数字和三个给定的运算符,您必须检查是否有办法将它们组合起来,将第n个数字作为解决方案。

输入是一组数字,输出为YN

示例

给定数字10 9 7 1 10 8。我们可以使用n-1个数字一次。该示例的输出为Y,因为存在一个解决方案,即(10-10)*9+(7+1)=8

我的方法到现在为止。

我很难找到解决问题的非暴力方法。我正在使用的基本想法是这个。 我将首先计算n-1个数字集的每个排列,然后插入数字之间的每个n-2空间,操作符的所有可能排列并评估结果表达式。我无法对此进行编码,而且我怀疑这是否正确。 请指导我如何解决问题。我正在使用C++

2 个答案:

答案 0 :(得分:1)

我认为基本上你会创造一大堆树。树的顶部有n-1个数字。您可以通过以下方式创建树的下一级:

  • 置换数字
  • 通过使用操作的排列组合相邻数字的子集来减少集合

重复此操作,直到集合缩小为1。

举例:10 9 7 1 10 8

  • 创建M个数字的排列:10 10 9 7 1
  • 选择大小为Q的相邻数字对的子集:10 107 1
  • 创建尺寸Q的操作的排列:**
  • 通过将相邻的数字对与操作组合来减少设置:10*10 => 1007*1 ==> 7
  • 您的新缩减集(我认为是树的下一个级别)是100 9 7

重复。您将为数字的每个排列,相邻数字的每个子集以及每个操作的排列创建一个新树。请记住,相邻数字子集的大小Q可以是[1,M / 2]。

对于“大”N,这将是内存和计算密集型。实际实施可能取决于您实际可用的硬件。一些优化可能是:

  • 如果您使用蛮力方法,请首先将尺寸Q保持在接近M / 2的位置。这将减少中间集的数量。
  • 记忆可能会有所帮助,但是会有如此多的可能组合,只需要执行int add / mul / sub就可以更快,如果你在英特尔上,则需要1个或3个周期。
  • 由于存在大量可能的减少树,我认为您需要使用类似遗传算法的方法来选择排列。

此外,这类问题实际上并不是C ++的优势......用scala甚至ruby等功能更强大的语言编写它会更容易。

酷问题BTW。

答案 1 :(得分:1)

我想到了两种方法:

  1. 在整数域上使用约束编程(CP)(eclipse,gnu prolog,...)。给出数字和运算符,CP将详尽地搜索所有可能的解决方案,或者如果您有点聪明,或者您的n不方便大,您可以通过注意不需要置换X和Y来指导搜索如果运算符是可交换的(+,*)。如果您需要完成工作,请使用此代码,因为代码大约为20行。

  2. Douglas Hofstadter(GEB成名)的一本名为“流体概念和创造性类比”的旧书由Daniel Defays描述了一个认知科学方法来解决问题(Numbo:认知和识别研究)。复制会有所涉及,但如果这本书有任何迹象,那将是非常有趣的。