【问题标题】:Finding best subarray sum and returning it and the subarray找到最佳子数组和并返回它和子数组
【发布时间】:2021-12-29 13:09:20
【问题描述】:

我对 Java 和编码也比较陌生,目前正在尝试解决子集问题。

目标是让用户输入数字的数量,然后输入每个数字,直到指定的数量,计算机相应地要求每个第 n 个数字。

然后计算机应计算所有子集的总和,并返回最接近 pi 的子集,以及同一行内这种形式 [x,y,z] 的子集。
我很好地管理了第一部分,尽管为了方便起见,它可能已经通过开关盒进行了改进。它将输入数字添加到数组中

但是我在这个问题的第二部分遇到了困难,我不知道如何推进/安排代码以输出所需的结果。我得到的建议是,一个包含 n 个元素的集合的 for 循环:

for a from 0 to 2^n
 for i from 0 to n
  when the binary representation of x on has a 1 at the i-th position
   add data[i] to solution.

这应该可以找到数组的所有子集。之后我应该添加每个元素,检查与 pi 的距离是否减小并将元素添加到解决方案集中。或者至少这是目标,但我的代码不起作用,因为我不知道从哪里开始安排它。我也不知道用什么来初始化 bestsum,或者二进制表示算法是如何工作的,或者如何按顺序将元素添加到解决方案数组中。 编辑:我已经取得了进展,下面的代码输出了所有子数组,它正确计算了最接近的总和,但我不知道如何“保存”最好的子数组(总和最接近的子数组),以便我可以在以总和结尾。我很新,所以我还没有学习列表甚至方法,但是本书在本章的这个问题,我想用建议的方法和可能只有简单的循环来解决它。

public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("How many numbers should be read? ");
        int count = input.nextInt();
        double[] data = new double[count];
        double [] solution = new double[count];
        double bestsum = 0.0;     
       


        for (int i = 0; i < count; i++) {
            if ((i + 1) % 10 == 1) {
                System.out.println("Enter " + (i + 1) + "st number: ");
                data[i] = input.nextDouble();
            } else if ((i + 1) % 10 == 2) {
                System.out.println("Enter " + (i + 1) + "nd number: ");
                data[i] = input.nextDouble();
            } else if ((i + 1) % 10 == 3) {
                System.out.println("Enter " + (i + 1) + "rd number: ");
                data[i] = input.nextDouble();
            } else {
                System.out.println("Enter " + (i + 1) + "th number: ");
                data[i] = input.nextDouble();
            }
        }
        for (int j = 0; j <(1 << count); j++) {
            System.out.print("{ ");
            double sum = 0.0;
            for (int x = 0; x < count; x++) {
                if ((j & (1 << x)) > 0) {
                    System.out.print(data[x] + " ");
                    sum = sum + data[x];
                }
                solution[x] = data[x];
            }


            System.out.println("}");
            if (Math.abs(sum - Math.PI) < Math.abs(bestsum - Math.PI)) {
                bestsum = sum;
            }
        }



System.out.println(bestsum);
        System.out.println(Arrays.toString(solution));

        }

    }

【问题讨论】:

    标签: java arrays subset


    【解决方案1】:

    这是我对这个问题的解决方案。

    public static void main(String[] args) {
        
        Scanner input = new Scanner(System.in);
        System.out.println("How many numbers should be read? ");
        int count = input.nextInt();
        Double data[] = new Double[count];
        Double bestsum = 0.0;
        List<Double> bestArray= Collections.emptyList();
        Set<List<Double>> possibleArrays = new LinkedHashSet<>();
        
    
    
        for (int i = 0; i < count; i++) {
            if (i == 0) {
                System.out.println("Enter " + (i+1) + "st number: ");
                data[i] = input.nextDouble();
            } else if (i == 1) {
                System.out.println("Enter " + (i+1) + "nd number: ");
                data[i] = input.nextDouble();
            } else if (i == 2) {
                System.out.println("Enter " + (i+1) + "rd number: ");
                data[i] = input.nextDouble();
            } else {
                System.out.println("Enter " + (i+1) + "th number: ");
                data[i] = input.nextDouble();
            }
    
        }
        input.close();
        for (int i = 0; i < (1<<count); i++)
        {
            int m = 1; // m is used to check set bit in binary representation.
            List<Double> currentArray = new ArrayList<>();
            for (int j = 0; j < count; j++)
            {
                if ((i & m) > 0)
                {       
                    currentArray.add(data[j]);
                }
                m = m << 1;
            }
            possibleArrays.add(currentArray);
        }
        Iterator<List<Double>> iterator = possibleArrays.iterator();
        iterator.next();
        for (int i = 1; i < possibleArrays.size(); i++) {
            Double sum=0.0;
            List<Double> currentArray = iterator.next();
            sum = currentArray.stream().collect(Collectors.summingDouble(Double::doubleValue));
            if(Math.abs(sum-Math.PI)<Math.abs(bestsum-Math.PI)) {
                bestArray = currentArray;
                bestsum = sum;
            }
            
        }
    
        System.out.println("possibleArrays: " + possibleArrays);
        System.out.println("solution: " + bestArray);
        System.out.println("bestsum: " + bestsum);
    
    }
    

    【讨论】:

    • 虽然我没有使用迭代器,但我可以很好地遵循逻辑。有没有办法处理集合中的多个相等元素?例如,如果第一个、第二个和第三个数字都是 1.0 ,那么它将导致最佳和为 1.0 与子集 [1.0] 而不是 3.0 与子集 [1.0 , 1.0 , 1.0]?
    • 已经在当前解决方案中得到照顾。我们正在创建集合,因此不会有重复的元素。
    • 确实如此,但我也在寻找一种计算重复项的方法,所以如果用户输入 1.0 3 次,那么解决方案应该是 3.0 和 [1.0, 1.0, 1.0]。我已经编辑了我的问题中的代码,因为我设法找到一种方法来计算这样的总和,但我不知道如何以这种方式保存最佳子集
    • 哦!对不起。集合没有重复项。如果我们正在考虑数组,则需要重新构建问题。您在寻找“数组”而不是“集合”吗?
    • 也许我在寻找子数组,因为我对它很陌生,这个问题只是在学习数组后才出现在我面前的。不包括 LinkedHasSets
    猜你喜欢
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 2021-05-14
    • 2013-03-01
    • 1970-01-01
    • 2016-07-25
    相关资源
    最近更新 更多