【问题标题】:How to multiply two long values in java如何在java中将两个长值相乘
【发布时间】:2018-08-26 12:13:46
【问题描述】:

我正在尝试将一个数字数组中的两个最大数字相乘。它适用于小数字。

正确的输入/输出 - 这是有效的:

3 10 2 8 80

正确的输入/输出 - 这是失败的:

2 100000 90000
9000000000

然而,我的输出是 10000000000。

谁能告诉我我的代码有什么问题?

public static Long sumPairwise(Long[] numbers){

        int index=0;
        int n = numbers.length;
        for(int i=1;i<n;i++){
            if(numbers[i]>numbers[index])
                    index=i;
        }
        numbers[n-1]= numbers[index];
        index=0;
        for(int j=1;j<n-1;j++){
        if(numbers[j]>numbers[index])
                index=j;
        }
        numbers[n-2]=numbers[index];
        Long product = (numbers[n-2])*(numbers[n-1]);

    return product ;
}
public static void main(String [] args){
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    Long numbers[] = new Long[n];
    for (int i=0;i<n;i++)
    numbers[i]= sc.nextLong();
    System.out.println(sumPairwise(numbers));

}

【问题讨论】:

  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建 minimal reproducible example。使用edit 链接改进您的问题 - 不要通过 cmets 添加更多信息。谢谢!

标签: java multiplication


【解决方案1】:

您的代码中有一个错误:numbers[n-1] 可能包含第二高的数字。在尝试将其放在第一个到最后一个位置之前,您正在用代码中的最高数字覆盖该数字。

解决这个问题的一种方法是使用Arrays.sort 对数组进行排序,这样您就可以确定最后两个数字是最高的数字和第二高的数字。

public static long multiplyLargestTwoNumbers(long[] numbers) {
    long[] sortedNumbers = numbers.clone();
    Arrays.sort(sortedNumbers);

    int size = numbers.length;
    // multiply highest and second highest number
    return sortedNumbers[size - 1] * sortedNumbers[size - 2];
}

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    long numbers[] = new long[n];
    for (int i = 0; i < n; i++) {
        numbers[i] = sc.nextLong();
    }
    System.out.println(multiplyLargestTwoNumbers(numbers));
}

其他变化:

  • 使用long而不是Long:在不需要目标引用类型时尝试使用原始类型(如果你想使用Long,例如List,因为List只能容纳对象引用);
  • 间隔for 循环,请使用空格;
  • 重命名方法,因为它不会成对添加任何东西;
  • 在 main 方法中为 for 循环使用了花括号;
  • 删除了部分执行乘法的伪括号。

您还可以引入if 语句,该语句首先检查numbers 数组是否确实包含至少两个元素。这称为保护声明

最后记住byteshortlong都包含特定位大小的有符号数。基本上你正在执行计算 modulus 2^n 其中 n 是位大小。如果值太大,它可能会溢出并返回不正确的结果。为此,您需要BigInteger

【讨论】:

  • 我会把它留在这里,因为它不会改变数组,因为它不会改变数组。
  • 是的。有一个错误。感谢您的帮助。
  • 不要忘记接受其中一个答案(并为有帮助的答案点赞)。在我看来,仅对于两个数字,Narayan 的答案更好,Array.sort 方法的扩展性更好(如果您想将最后的 3 或 4 相乘而不是最后的 2。
  • clone()有什么用
  • 一般你不希望方法有副作用。请注意,该数组是通过引用传递的,因此该数组也将在方法之外进行排序。这不是您在调用此函数时所期望的。
【解决方案2】:

您正在将该索引中的原始数字替换为另一个数字。 这就是问题所在。

请简单地从下面的逻辑中找到最多 2 个数字并相乘。 另外,记得关闭扫描仪。

这里是简单的解决方案。这仅适用于正整数。

import java.util.Scanner;

    public class Snippet {
        public static long multiplyHighestTwoValues(Long[] numbers) {

            long maxOne = 0;
            long maxTwo = 0;
            for (long n : numbers) {
                if (maxOne < n) {
                    maxTwo = maxOne;
                    maxOne = n;
                } else if (maxTwo < n) {
                    maxTwo = n;
                }
            }

            long product = maxOne * maxTwo;
            return product;
        }

        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            Long numbers[] = new Long[n];
            for (int i = 0; i < n; i++)
                numbers[i] = sc.nextLong();
            System.out.println(sumPairwise(numbers));
            sc.close();

        }
    }

【讨论】:

  • 不要关闭绑定到System.in 的扫描器,因为它会关闭底层资源,即System.in。仅关闭您自己打开的资源。 System.in 由 JVM 管理。
  • 是的。有一个错误。感谢您的帮助。
【解决方案3】:

请尝试使用BigInteger 来乘以适合long 的更大值而不是Long,否则您的结果可能溢出

使用BigDecimal 代替浮点数相乘。

【讨论】:

  • @MaartenBodewes,她使用的数字将适用于长数据类型。 BigInteger 不是必需的。该程序没有因为它的数据类型而失败。它只是有一个错误。
  • @NarayanParvatikar long 和 Long 之间的值范围没有区别。你的评论没有意义。
  • Precision 是错误的词,您的意思可能是:range
  • @GhostCat 我告诉我们可以使用 long/Long 而不是 BigInteger。希望你能明白。
  • @NarayanParvatikar 你之前没这么说,这就是区别。微妙的细节很重要;-)
猜你喜欢
  • 1970-01-01
  • 2017-04-02
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多