Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.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
Java 四和实现的二次时间_Java_Arrays_Algorithm_Quadratic_Cubic - Fatal编程技术网

Java 四和实现的二次时间

Java 四和实现的二次时间,java,arrays,algorithm,quadratic,cubic,Java,Arrays,Algorithm,Quadratic,Cubic,给定一个包含x元素的数组,我必须找到四个当求和时等于零的数字。我还需要确定存在多少这样的金额 所以立方时间包含三个嵌套迭代器,所以我们只需查找最后一个数字(使用二进制搜索) 相反,通过使用笛卡尔积(X和Y的相同数组),我们可以将所有对及其和存储在一个辅助数组中。因此,对于每个求和d,我们只需查找-d 这应该类似于(接近)二次时间: public static int quad(Double[] S) { ArrayList<Double> pairs = new ArrayLis

给定一个包含
x
元素的数组,我必须找到四个当求和时等于零的数字。我还需要确定存在多少这样的金额

所以立方时间包含三个嵌套迭代器,所以我们只需查找最后一个数字(使用二进制搜索)

相反,通过使用笛卡尔积(X和Y的相同数组),我们可以将所有对及其和存储在一个辅助数组中。因此,对于每个求和
d
,我们只需查找
-d

这应该类似于(接近)二次时间:

public static int quad(Double[] S) {
  ArrayList<Double> pairs = new ArrayList<>(S.length * S.length);
  int count = 0;

  for (Double d : S) {
    for (Double di : S) {
      pairs.add(d + di);
    }
  }

  Collections.sort(pairs);

  for (Double d : pairs) {
    int index = Collections.binarySearch(pairs, -d);
    if (index > 0) count++; // -d was found so increment
  }

  return count;
}

双精度有可能丢失吗

编辑:讨论了使用
BigDecimal
代替
double
,但我们担心这会影响性能。我们只处理阵列中的353个元素,所以这对我们有什么意义吗

编辑:如果我错误地使用了BigDecimal,我道歉。我以前从未和图书馆打过交道。因此,在多次建议之后,我尝试使用BigDecimal

public static int quad(Double[] S) {
  ArrayList<BigDecimal> pairs = new ArrayList<>(S.length * S.length);
  int count = 0;

  for (Double d : S) {
    for (Double di : S) {
      pairs.add(new BigDecimal(d + di));
    }
  }

  Collections.sort(pairs);

  for (BigDecimal d : pairs) {
    int index = Collections.binarySearch(pairs, d.negate());
    if (index >= 0) count++;
  }

  return count;
}

在这里,您应该使用
BigDecimal
类而不是
double
,因为数组中的浮点数加起来等于0的精确精度对于您的解决方案来说是必须的。如果您的一个十进制值是.1,您就有麻烦了。这个二进制分数不能用
double
精确表示。以以下代码为例:

double counter = 0.0;
while (counter != 1.0)
{
    System.out.println("Counter = " + counter);
    counter = counter + 0.1;
}
您可能期望它执行10次,但这是一个无限循环,因为计数器永远不会精确到1.0

示例输出:

Counter = 0.0
Counter = 0.1
Counter = 0.2
Counter = 0.30000000000000004
Counter = 0.4
Counter = 0.5
Counter = 0.6
Counter = 0.7
Counter = 0.7999999999999999
Counter = 0.8999999999999999
Counter = 0.9999999999999999
Counter = 1.0999999999999999
Counter = 1.2
Counter = 1.3
Counter = 1.4000000000000001
Counter = 1.5000000000000002
Counter = 1.6000000000000003

在搜索成对或单个元素时,需要使用多重性进行计数。也就是说,如果您在单例或成对数组中找到元素-d,那么您需要将计数增加找到的匹配数,而不仅仅是增加1。这可能就是为什么在成对搜索时无法获得全部结果的原因。这可能意味着当你搜索单件时,528个匹配的数字并不是真正的完整数字。一般来说,不应该使用双精度算法来实现精确算法;改用任意精度的有理数包。

这不是二次曲线。它是
O(n^2logn)
pairs
的大小是
n^2
-你可以在
O(n^2*log(n^2))=O(n^2logn)
编辑文章。它应该是接近二次的,所以
O(n^2 log(n))
也应该可以。“double的精度是不是碰巧丢失了?”-如果你想知道的话,假设“是”(只是……作为一个规则)。比较double是否相等总是一个非常糟糕的主意。
If(index>0)
If(index>=0)
?我更新了我的帖子,使用了BigDecimal。确实提高了4(从257提高到261),所以这可能是一个精度损失问题。不幸的是,BD没有修复它
double counter = 0.0;
while (counter != 1.0)
{
    System.out.println("Counter = " + counter);
    counter = counter + 0.1;
}
Counter = 0.0
Counter = 0.1
Counter = 0.2
Counter = 0.30000000000000004
Counter = 0.4
Counter = 0.5
Counter = 0.6
Counter = 0.7
Counter = 0.7999999999999999
Counter = 0.8999999999999999
Counter = 0.9999999999999999
Counter = 1.0999999999999999
Counter = 1.2
Counter = 1.3
Counter = 1.4000000000000001
Counter = 1.5000000000000002
Counter = 1.6000000000000003