24点扩展-任意多数经过四则运算得到一个新数(n数n点,matlab程序)
水一篇。由于家长群里经常发各种‘益智’题,比如4个6怎样凑成5,123456怎样得到20呀之类的,所以不厌其烦,干脆写一个程序,一劳永逸。
1 大概思路
以下面问题为例:
1 2 3,如何添加 加减乘除 运算和括号,得到4。
(要加入指数幂运算,可以添加^符号,我怕电脑算炸,没敢加)
正确答案为:
2*(3-1)=4
(3+2)-1=4
。。。等等
观察等式,式子中包含了数字、符号和运算顺序三大类。改变这三大类,我们可以得到不同的排列组合
如上图所示,其中N代表参与排列的数字,图中123三个,所以N=3。其中数字的排列种类有N!,以阶乘的速度增长。符号的变化种类为4^(N-1)种,以指数速度增长。而计算顺序有(N-1)!,也是以阶乘的速度在增长。
因此,如果把所有组合都暴力尝试一遍,则会有:
N ! ∗ 4 N − 1 ∗ ( N − 1 ) ! N!*4^{N-1}*(N-1)! N!∗4N−1∗(N−1)!
当N等于3的时候,只需要计算192次;
当N等于4的时候,需要计算9216次;
当N等于5的时候,需要计算737280次。
这种爆炸式增长使得在计算数据量较大的数据时,会非常慢。
因此不用说,这种算法的缺点就是计算量太大。而且从算法设计本身,就涉及到3层循环计算,对matlab十分不友好,会导致速度更慢。而且算法采用字符串调用eval函数的方法,matlab的eval函数速度又比较慢,所以效率更差。(没救了,没救了)
1.1 数字排列算法
这里直接采用matlab里的函数perms()进行排列组合,包含了输入向量所有可能的排序。
1.2 符号排序算法
符号排序属于重复的全排列,每个符号都可以重复的出现。
这里采用的是下面这篇文章的思路:
matlab如何实现重复数全组合问题
文章采用ndgrid函数生成不重复的N维网格,然后将每个独一无二的网格点坐标,作为全排列的点。
1.3 计算顺序括号算法
括号算法采用逐级合并的方式进行,以下面的图为例(Mermaid流程图打不出括号,用<>代替括号):