此答案基于 math.stackexchange 上此问题的公认答案:
https://math.stackexchange.com/questions/354625/how-to-compose-given-add-sub-mult-div-functions-to-map-an-integer-m-to-n
给定六个输入(a、b、c、d、M、N)
- a:我们可以添加的数字
- b:我们可以减去的数字
- c:我们可以乘的数
- d:我们可以除的数
- M:起始编号
- N:结束编号
我假设它们都是整数,并且a> 0,b> 0,c可以是正数或负数,d不等于0。
然后有一种方法可以通过应用 add、sub、mult、div 将 M 转换为 N,
当且仅当
存在整数 m 和 n 使得
因此,首先要做的是找到 a 和 b 的最大公约数(我推荐这里描述的欧几里德算法。将 gcd 称为“g”。
mod应用于双方以验证相等性。
因此,开始列出左侧对于不同 m 可以取的可能值:
(M*( Pow(c,m) )) % g
然后,开始列出右侧对于不同 n 可以取的可能值:
(N*( Pow(d,n) )) % g
您将希望从零开始 m 和 n 并逐步向上。
最终,双方将开始重复,因为您正在使用 mod。
如果您在任何时候找到匹配项,即左侧等于某个右侧,则返回 1。
否则,一旦您用尽了所有左手值和右手值,没有匹配项,则返回 0。
请注意,C++ 中的 mod 运算符 (%) 对于负数的行为确实与上述数学描述的不同。您需要将 mod 的结果调整为始终在 0 <= result < g 范围内
最后,这仅适用于除法根据正常数学进行的情况,即 3 / 2 = 1.5 等等。
在您的情况下,您需要稍微修改公式以接受整数除法。特别是等式的右手边处理除法。有点像下面的等式是如何工作的,我们可以取一个除法,把它移到另一边,它就变成了一个乘法。
x / 3 = 1
x = 1*3
每次对 d 执行电源时,您都需要允许 rhs 取多个值。例如,在上面的例子中,我们需要让 1*3 等于 3,4 或 5。
所以,如果 d = 3,那么
- Pow(d,0) = 1。
- Pow(d,1) = 3 或 4 或 5。
- Pow(d,2) = 9 或 10 或 11 或 12 或 13 或 14 或 15 或 16 或 17
您将看到 9 = 3*3、12 = 4*3 和 15 = 5*3。因此,即使对于不同的 d 值,该模式也应该易于复制。
我还没有尝试过最后一部分,所以我不完全确定这是否完全涵盖了整数除法的所有情况,但我认为确实如此,尽管它有点乏味。