Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 算法思维指导(4-4方程)_Algorithm_Computation Theory - Fatal编程技术网

Algorithm 算法思维指导(4-4方程)

Algorithm 算法思维指导(4-4方程),algorithm,computation-theory,Algorithm,Computation Theory,我最近看到了一个逻辑/数学问题,名为4-Fours,其中需要使用4-Fours和一系列运算符来创建等于所有整数0到N的方程 你将如何着手编写一个优雅的算法来提出,比如说第一个100 我从创建基本计算开始,比如4-4、4+4、4x4、4/4、4!,Sqrt 4并将这些值设为整数 然而,我意识到这将是一个蛮力方法来测试组合,看看它们是否相等,0,然后1,然后2,然后3等等 然后,我想找到所有可能的上述值的组合,检查结果是否小于100,填充一个数组,然后对其进行排序……同样效率低下,因为它可能会找到1

我最近看到了一个逻辑/数学问题,名为4-Fours,其中需要使用4-Fours和一系列运算符来创建等于所有整数0到N的方程

你将如何着手编写一个优雅的算法来提出,比如说第一个100

我从创建基本计算开始,比如4-4、4+4、4x4、4/4、4!,Sqrt 4并将这些值设为整数

然而,我意识到这将是一个蛮力方法来测试组合,看看它们是否相等,0,然后1,然后2,然后3等等

然后,我想找到所有可能的上述值的组合,检查结果是否小于100,填充一个数组,然后对其进行排序……同样效率低下,因为它可能会找到1000个大于100的数字

任何关于如何处理这样的问题的帮助都是有帮助的…不是实际的代码…而是如何思考这个问题


谢谢

我认为暴力解决方案是唯一的出路。
这背后的原因是,每个数字都有不同的到达方式,到达某个
x
可能与到达
x+1
无关

话虽如此,通过尽可能使用明显的动作,您可能会使暴力解决方案更快一些。

例如,如果我用“4”三次达到20(
4*4+4
),很明显达到16、24和80。持有一个100位的数组并标记达到的数字

类似于子集和问题,可以使用以下递归公式来解决:

D(0,0) = true
D(x,0) = false     x!=0
D(x,i) = D(x-4,i-1) OR D(x+4,i-1) OR D(x*4,i-1) OR D(x/4,i-1)
通过使用DP技术计算上面的数字,很容易找到使用这4个数字可以生成哪些数字,通过回溯解决方案,您可以找到每个数字是如何生成的


此方法的优点(当使用DP实现时)是不需要多次重新计算多个值。我不确定它是否真的对4 4有效,但我相信从理论上讲,对于这个问题的一个较少限制的推广来说,它可能是一个显著的改进。

这个答案只是Amit的一个扩展。 基本上,您的操作是:

  • 对现有表达式应用一元运算符以获取新表达式(这不使用任何额外的4s)
  • 对两个现有表达式应用二进制运算符以获得新表达式(新表达式的4s数等于两个输入表达式之和)
  • 对于1..4中的每个
    n
    ,计算
    表达式(n)
    -如下所示的(表达式,值)对列表: (对于固定的
    n
    ,在列表中仅存储一个计算结果为任何给定值的表达式)

  • 使用
    n
    4s(即4、44、444、4444)的串联来初始化列表
  • 对于
    i
    从1到
    n-1
    ,以及每个允许的二进制运算符
    op
    ,添加表达式(和值)
    e1 op e2
    ,其中
    e1
    表达式(i)
    中,而
    e2
    表达式(n-i)
  • 重复将一元运算符应用于步骤1-3中迄今为止计算的表达式/值。何时停止(递归地应用3)有点模糊,如果迭代没有产生新值,当然要停止。可能会限制允许值的大小或表达式的大小 示例一元运算符是
    Sqrt
    -
    等。示例二进制运算符为
    +-*/^
    等。如果允许,您可以轻松地将此方法扩展到具有更多参数的运算符


    对于任何给定的
    n
    ,您可以在步骤3中做一些更聪明的事情,永不停止。在所有
    j
    表达式(j)
    完成之前,简单方法(如上所述)不会开始计算
    表达式(i)
    。这要求我们知道何时停止。另一种方法是为每个
    n
    构建具有特定最大长度的表达式,然后如果需要(因为没有找到特定的值),可以在外部循环中扩展最大长度。

    这是一个有趣的问题。这里发生了两件不同的事情。一个问题是如何描述进入算术表达式的操作和操作数序列。使用括号来建立运算顺序是相当混乱的,因此我建议将表达式看作是一组运算和操作数,比如4-4的
    -4 4
    ,(4*4)+4的
    +4*4
    ,(4+4)*4的
    *4+4
    ,等等。这就像HP计算器上的反向波兰符号。这样你就不必担心括号了,当我们构建越来越大的表达式时,拥有表达式的数据结构将在下面有所帮助

    现在我们转向构建表达式的算法。在我看来,动态规划在这种情况下不起作用,因为(例如)要构造一些介于0到100之间的数字,可能需要暂时超出该范围

    我认为,更好的概念化问题的方法是在图上进行广度优先搜索(BFS)。从技术上讲,这个图是无限的(所有的正整数,或所有的整数,或所有的有理数,这取决于你想得到的详细程度),但在任何时候你只有一个图的有限部分。稀疏图数据结构是合适的

    图上的每个节点(数字)都有一个与之相关联的权重、到达该节点所需的最小4个数,以及实现该结果的表达式。最初,您只需要从节点(4)开始,用与之相关联的数字1(用一个4表示4)和简单表达式“4”。你也可以投(44)重2,投(444)重3,投(4444)重4

    要构建更大的表达式,请将所有不同的操作应用于这些初始节点。例如,一元否定、阶乘、sq