比较一对3个变量的数学方法 - java

在Java中,我被分配以比较两个3个正双变量,而忽略它们的顺序。
我做了以下事情:

if ((a1 == a2 && b1 == b2 && c1 == c2) ||
    (a1 == a2 && b1 == c2 && c1 == b2) ||
    (a1 == b2 && b1 == a2 && c1 == c2) ||
    (a1 == b2 && b1 == c2 && c1 == a2) ||
    (a1 == c2 && b1 == a2 && c1 == b2) ||
    (a1 == c2 && b1 == b2 && c1 == a2))
    // if true

我从老师那里听说,有一种数学方法可以比较这对3个数字。

到目前为止,我试图将它们的加,减,乘幂之和与2进行比较,但是我总是发现这样的情况,即该对是不同的,并且陈述是正确的。

有任何想法吗?

编辑:

我已经发送了作业,老师说我的回答是正确的。我出于好奇而问。

参考方案

TL; DR

比较每个三元组的总和,每个三元组的乘积以及每个三元组的所有可能组合的乘积之和。

坚韧不拔

通过Fundamental Theorem of Algebra,对于次数为N的多项式,我们必须具有N个根。

利用这个事实,我们将零设为a1, a2, and a3。现在,我们找到该多项式的系数。

(x - a1) * (x - a2) * (x - a3)
(x^2 - (a1 + a2) * x + a1a2) * (x - a3) 
x^3 - (a1 + a2) * x^2 + (a1a2) * x - a3 * x^2 + (a1a3 + a2a3) * x - a1a2a3

x^3 + (-1 * (a1 + a2 + a3)) * x^2 + (a1a2 + a1a3 + a2a3) * x + (-1 * a1a2a3)

如果两个多项式是等价的,则它们必须具有相同的根(FTA同样)。因此,我们要做的就是比较所生成多项式的系数。

因此,如果,

(-1 * (a1 + a2 + a3) == (-1 * (b1 + b2 + b3))
      ---equivalently---
a1 + a2 + a3 == b1 + b2 + b3

(a1a2 + a1a3 + a2a3) == (b1b2 + b1b3 + b2b3)

-1 * a1a2a3 == -1 * b1b2b3
      ---equivalently---
a1a2a3 == b1b2b3

然后我们可以得出结论,三元组a1, a2, a3b1, b2, b3是等效的。

这值得么?

从实际的角度来看,让我们看一下这是否确实比OP所示的蛮力检查更有效。

首先检查:求和与比较。这总共需要4次加法和1次检查是否相等。

检查总数= 5;跑步总数= 5

第二次检查:乘积,求和和比较。这需要6次总乘法,4次总加法和1次相等检查。

检查总数= 11;跑步总数= 16

第三项检查:乘积和比较。这需要4次总乘法和1次相等检查。

检查总数= 5;跑步总数= 21

将两个逻辑“与”运算相加,“生成的多项式方法的系数”的二进制运算总数仅需要:

23个二进制运算

蛮力检查需要进行18项相等性检查,12项逻辑AND比较和5项逻辑OR比较,总共需要:

35个二元运算

因此,严格来说,答案是肯定的,“生成的多项式方法的系数”确实更有效。但是,正如@WJS指出的那样,蛮力方法为short circuiting提供了更多机会,因此比数学方法执行效率更高。

彻底彻底

我们不能跳过检查每个三元组所有可能组合的乘积之和。如果我们忽略这一点,那么有无数个失败的例子。考虑(23, 32, 45)(24, 30, 46) *:

23 + 32 + 45 = 100
24 + 30 + 46 = 100

23 * 32 * 45 = 33120
24 * 30 * 46 = 33120

它们不相等,但给出相同的总和和积。但是,它们给出的所有可能组合的乘积之和不相同:

23 * 32 + 23 * 45 + 32 * 45 = 3211
24 * 30 + 24 * 46 + 30 * 46 = 3204

*如果想知道如何得出与上述示例相似的示例,请首先生成长度为3的整数M的所有整数分区,取其乘积,查找重复项,然后选择一对。

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…